`

发短信算法题

阅读更多

发短信:手机短信通常a个字就分一页,分页之前在短信之前都要加上(1/n)、(2/n)...,当然啦,这个要加到每页的字数里面。短信放送之前,头部加上“您好:”,结尾要加上“【AB公司】”,这些也当然要加入字数里面,现在请写一方法来显示每条短信的内容。程序的难点在于怎样获取总页数,而且要判断在什么情况下是不能显示所有的信息内容的

 

package com.fun;

import java.util.Scanner;

public class MessagePaging {
	private static final int MaxWordsOnePage = 10;
	private static final String prefix = "您好:";
	private static final String suffix = "【AB公司】";
	private String pageBaseStr = "(%d/%d)";
	final int baseLen = 3; // ( / ), the three character

	public static void main(String[] args) {
		MessagePaging paging = new MessagePaging();
		paging.run();
	}

	private void run() {
		System.out.println("please input message:");
		Scanner scanner = new Scanner(System.in);
		String content;
		while ((content = scanner.nextLine()).length() != 0) {
			String result = parseMessage(content);
			System.out.println("result: " + result);
			for(int i = 0; i < result.length(); i+=MaxWordsOnePage){
				int max = (i+MaxWordsOnePage) >= result.length() ? (result.length()) : (i + MaxWordsOnePage);
				String str = result.substring(i, max);
				System.out.println(i + ":" + str + ",len:" + str.length());
			}
		}
		System.out.println("finish");
	}

	public String parseMessage(String content) {
		StringBuffer sb = new StringBuffer(content);
		insertPrefix(sb);
		appendSuffix(sb);
		if (!hasNextPage(sb)) {
			return sb.toString();
		}
		int page = 1;
		int totalPage = getTotalPage(sb.length());
		checkInvalidTotalPage(totalPage,sb.length());
		while (page <= totalPage) {
			 insertPageMessage(sb, page, totalPage); //String pageContent =
//			 System.out.println(pageContent);
			++page;
		}
		return sb.toString();
	}

	private void checkInvalidTotalPage(int totalPage, int contentLength) {
		if (totalPage < 2) {
			System.out.println("totalPage " + totalPage + " less than 2");
			System.exit(0);
		}
		String pageMes = String.format(pageBaseStr, totalPage, totalPage);
		if (pageMes.length() >= MaxWordsOnePage) {
			System.out.println("page message:" + pageMes
					+ " is no longer than max words in one page len:"
					+ MaxWordsOnePage);
			System.exit(0);
		}
	}

	private int getTotalPage(final int contentLength) {
		int total = calculateMinTotal(contentLength);
		while (calculateTotal(contentLength, total) != total) {
			++total;
			checkInvalidTotalPage(total,contentLength);
		}
		return total;
	}
	
	private int calculateMinTotal(int contentLength){
		int tmpTotalPage = contentLength / MaxWordsOnePage + 1;
		int lowLen = baseLen + 2 * getDigits(tmpTotalPage);
		return (contentLength + tmpTotalPage*lowLen)/MaxWordsOnePage;
	}

	private int calculateTotal(int contentLength, int total) {
		int totalLength = contentLength + getTotalPageLen(total);
		int addOne = ((totalLength % MaxWordsOnePage) == 0 ? 0 : 1);
		return totalLength / MaxWordsOnePage + addOne;
	}

	private int getTotalPageLen(int total) {
		int lowLen = baseLen + 1 + getDigits(total);
		int highLen = baseLen + 2 * getDigits(total);
		int sumLen = 0;
		for (int i = 1; lowLen <= highLen; ++i) {
			sumLen += lowLen * getLenCount(total, i);
			++lowLen;
		}
		return sumLen;
	}

	private int getLenCount(int total, int i) {
		int low = (int) Math.pow(10, i - 1);
		int high = (int) Math.pow(10, i) - 1;
		if (total >= low && total <= high) {
			return total - low + 1;
		}
		return 9 * low;
	}

	// 获取数字的位数
	private int getDigits(int total) {
		int count = 0;
		while (total != 0) {
			total /= 10;
			count++;
		}
		return count;
	}

	private String insertPageMessage(StringBuffer sb, int page, int totalPage) {
		String pageMes = String.format(pageBaseStr, page, totalPage);
		sb.insert((page - 1) * MaxWordsOnePage, pageMes);
		int max = page * MaxWordsOnePage >= sb.length() ? sb.length()
				: (page * MaxWordsOnePage);
		return sb.substring((page - 1) * MaxWordsOnePage, max);
	}

	private boolean hasNextPage(StringBuffer sb) {
		return sb.length() > MaxWordsOnePage;
	}

	private StringBuffer insertPrefix(StringBuffer content) {
		return content.insert(0, prefix);
	}

	private StringBuffer appendSuffix(StringBuffer content) {
		return content.append(suffix);
	}

}
 

 

 

分享到:
评论

相关推荐

    多任务下的数据结构与算法

    本书和传统同类书籍的区别是...为了便于读者自学,每章末附有小结和思考练习题。 本书可供高校计算机及相关专业作为教学参考书,对从事软件开发与应用的科研人员、工程技术人员以及其他相关人员也具有较高的参考价值。

    C语言网络教学平台

    课程考试(可以随机或指定课程作业题型组卷并能全部自动判卷)、学生空间(包括个人资料、我的问题、我的收藏、我的笔记、我的短信、我的文件等),文章精选(分类收录大量有关C语言程序设计相关的文章和典型算法...

    网络安全知识读本(1).doc

    网络交易平台向用户绑定的手机号码发出一次性口令短信,也就是口令卡 【单选题】 第(18) 题 我国维护网络空间安全以及参与网络空间国际治理所坚持的指导原则是()。 【2分】 A. 网络主权原则 B. 网络安全战略原则 ...

    网络安全知识读本.doc

    网络交易平台向用户绑定的手机发出一次性口令短信,也就是口令卡 【单项选择题】 第〔18〕 题 我国维护网络空间平安以及参与网络空间国际治理所坚持的指导原那么是()。 【2分】 A. 网络主权原那么 B. 网络平安战略...

    vc++ 开发实例源码包

    如题,此实例非常适合学习,重载并自绘了Wnd类,效果是上下文字、图片、文字由大到小和星星闪烁等滚动效果。实例使用了加载类似xml文件读取信息,然后显示。 COM_ATL_Tutorial 简单的atl控件演示 COM接口挂钩及其...

    java源码包---java 源码 大量 实例

     //给客户发一个感谢消息,消息驱动Bean必须实现两个接口MessageDrivenBean和MessageListener  在对象创建的过程中将被容器调用,onMessage函数方法接收消息参数,将其强制转型为合适的消息类型,同时打印出消息...

    java源码包2

     //给客户发一个感谢消息,消息驱动Bean必须实现两个接口MessageDrivenBean和MessageListener  在对象创建的过程中将被容器调用,onMessage函数方法接收消息参数,将其强制转型为合适的消息类型,同时打印出消息...

    java源码包3

     //给客户发一个感谢消息,消息驱动Bean必须实现两个接口MessageDrivenBean和MessageListener  在对象创建的过程中将被容器调用,onMessage函数方法接收消息参数,将其强制转型为合适的消息类型,同时打印出消息...

    java源码包4

     //给客户发一个感谢消息,消息驱动Bean必须实现两个接口MessageDrivenBean和MessageListener  在对象创建的过程中将被容器调用,onMessage函数方法接收消息参数,将其强制转型为合适的消息类型,同时打印出消息...

    成百上千个Java 源码DEMO 4(1-4是独立压缩包)

    Message-Driven Bean EJB实例源代码 2个目标文件 摘要:Java源码,初学实例,EJB实例 Message-Driven Bean EJB实例源代码,演示一个接收购物订单的消息驱动Bean,处理这个订单同时通过e-mail的形式 //给客户发一个感谢...

    成百上千个Java 源码DEMO 3(1-4是独立压缩包)

    Message-Driven Bean EJB实例源代码 2个目标文件 摘要:Java源码,初学实例,EJB实例 Message-Driven Bean EJB实例源代码,演示一个接收购物订单的消息驱动Bean,处理这个订单同时通过e-mail的形式 //给客户发一个感谢...

    JAVA上百实例源码以及开源项目

     //给客户发一个感谢消息,消息驱动Bean必须实现两个接口MessageDrivenBean和MessageListener  在对象创建的过程中将被容器调用,onMessage函数方法接收消息参数,将其强制转型为合适的消息类型,同时打印出消息...

    JAVA上百实例源码以及开源项目源代码

    Message-Driven Bean EJB实例源代码 2个目标文件 摘要:Java源码,初学实例,EJB实例 Message-Driven Bean EJB实例源代码,演示一个接收购物订单的消息驱动Bean,处理这个订单同时通过e-mail的形式 //给客户发一个感谢...

    vc++ 应用源码包_1

    如题,此实例非常适合学习,重载并自绘了Wnd类,效果是上下文字、图片、文字由大到小和星星闪烁等滚动效果。实例使用了加载类似xml文件读取信息,然后显示。 COM_ATL_Tutorial 简单的atl控件演示 COM接口挂钩及其...

    vc++ 应用源码包_2

    如题,此实例非常适合学习,重载并自绘了Wnd类,效果是上下文字、图片、文字由大到小和星星闪烁等滚动效果。实例使用了加载类似xml文件读取信息,然后显示。 COM_ATL_Tutorial 简单的atl控件演示 COM接口挂钩及其...

    vc++ 应用源码包_6

    如题,此实例非常适合学习,重载并自绘了Wnd类,效果是上下文字、图片、文字由大到小和星星闪烁等滚动效果。实例使用了加载类似xml文件读取信息,然后显示。 COM_ATL_Tutorial 简单的atl控件演示 COM接口挂钩及其...

    vc++ 应用源码包_5

    如题,此实例非常适合学习,重载并自绘了Wnd类,效果是上下文字、图片、文字由大到小和星星闪烁等滚动效果。实例使用了加载类似xml文件读取信息,然后显示。 COM_ATL_Tutorial 简单的atl控件演示 COM接口挂钩及其...

    vc++ 应用源码包_3

    如题,此实例非常适合学习,重载并自绘了Wnd类,效果是上下文字、图片、文字由大到小和星星闪烁等滚动效果。实例使用了加载类似xml文件读取信息,然后显示。 COM_ATL_Tutorial 简单的atl控件演示 COM接口挂钩及其...

    C#开发典型模块大全(光盘)

    10.2.1 阴阳历转换算法 10.2.2 调用系统API实现鼠标穿透效果 10.2.3 修改注册表控制程序开机自启动 10.2.4 通过控制窗体透明度实现日历透明显示效果 10.2.5 拖动无标题栏窗体 10.2.6 将窗体的关闭位置写入到注册表中...

Global site tag (gtag.js) - Google Analytics