短信切割算法

  在一个项目中,要用到手机发送短信,但是使用的短信猫却无法支持大于70个字符的情况,而且经常收到有朋友的短信,比较长的手机都会自动将它切成几个短信发送。有时候很搞,收到的短信有两条,第二条就只有一个句号而已。或者几乎这种手机都不会去理解语义,直接就在70个字符处切割。

    要做到完全理解语义也不大可能,但是突然想到,为什么不可以根据分隔符去切割呢?至少这样子不会把一段完整的内容不会被强行分割出来。

    比如有下面一段话: 

如果短信的长度超过70个字符,程序就会自动根据短信中的分隔符进行分割,在不是非常苛刻的情况下,它不会将一个词分成两段来发,比如,不会出现"你好"的前一个字在第一条短信内,而""字在第二条短信内!这都是在不增加短信数量的情况下优化的!

    普通的短信会分成:

     1. 如果短信的长度超过70个字符,程序就会自动根据短信中的分隔符进行分割,在不是非常苛刻的情况下,它不会将一个词分成两段来发,比如,不会出现"(70个字符)

     2."的前一个字在第一条短信内,而""字在第二条短信内!这都是在不增加短信数量的情况下优化的!(47个字符)

     使用下面的程序,可以得到以下的另一种分法:

     1.如果短信的长度超过70个字符,程序就会自动根据短信中的分隔符进行分割,在不是非常苛刻的情况下,它不会将一个词分成两段来发,比如,(待续)==>68
     2.(续)不会出现"你好"的前一个字在第一条短信内,而"好"字在第二条短信内!这都是在不增加短信数量的情况下优化的!==>56

很显然,第二种情况才是比较人性化一点的。看看程序吧:

 


        private const String PRE_STR = "(续)";

        
private const String SUF_STR = "(待续)";

        
private static int PRE_STR_LEN = PRE_STR.Length;

        
private static int SUF_STR_LEN = SUF_STR.Length;

        
private static int EXT_LENGTH = PRE_STR_LEN + SUF_STR_LEN;

        
private static int MAX_LEN = 70//每个短信最长大小

        
/// <summary>
        
/// 切割字符串,使每串不超过70个字符
        
/// </summary>
        
/// <param name="str"></param>
        
/// <returns></returns>
        private List<String> StringSplit(String str)
        {
            List
<String> msms = new List<string>();
            
bool star = true;
            
while (true)
            {
                
if (!star)
                {
                    str 
= PRE_STR + str;
                }
                
int lenght = str.Length;
                
int msgCoun = getMsgCount(lenght);
                
int nullSpace = getLastMsgLeftCount(lenght, msgCoun);
                
if (str.Length <= MAX_LEN)
                {
                    
//不用分割
                    msms.Add(str);
                    
break;
                }
                
else
                {
                    
int splitIndex = getSplitIndex(str, nullSpace);
                    
string tempStr = str.Substring(0, splitIndex);
                    msms.Add(tempStr 
+ String SUF_STR);
                    str 
= str.Substring(splitIndex);
                }
                star 
= false;
            }
            
return msms;
        }

        
/// <summary>
        
/// 获取一条短信最小可以分多少条短信
        
/// </summary>
        
/// <param name="t">短信长度</param>
        
/// <returns></returns>
        private int getMsgCount(int t)
        {
            
if (t < MAX_LEN)
                
return 1;
            
int n = (int)((t + MAX_LEN - 2 * EXT_LENGTH - 1/ (MAX_LEN - EXT_LENGTH));
            
return n;
        }

        
/// <summary>
        
/// 计算最后一条信息还可添加多少个字符
        
/// </summary>
        
/// <param name="t">短信总字符数</param>
        
/// <param name="n">短信理想情况分页数</param>
        
/// <returns></returns>
        private int getLastMsgLeftCount(int t,int n)
        {
            
if (t <= MAX_LEN)
                
return MAX_LEN - t;
            
int l = MAX_LEN + (MAX_LEN - EXT_LENGTH) * (n - 1- t;
            
return l;
        }

        
private static char[] splitChar = new char[] { ',',' ','.',';','!',')','>','}',']','',' ','','','','','','"n','"t'};

        
/// <summary>
        
/// 比较智能地去判断分割的位置,尽量在有分隔符的地方分割
        
/// </summary>
        
/// <param name="str">str的长度一定大于MAX_LEN</param>
        
/// <param name="space">剩余可用空间大小</param>
        
/// <returns></returns>
        private int getSplitIndex(String str,int space)
        {
            
if (space > 0)
            {
                
for (int i = MAX_LEN - SUF_STR_LEN - 1, d = (MAX_LEN - SUF_STR_LEN - space - 1); i >= d; --i)
                {
                    
foreach (char c in splitChar)
                    {
                        
if (str[i] == c)
                        {

                            
//匹配
                            Console.WriteLine(i + 1);
                            
return i + 1;
                        }
                    }
                }
            }
            
return MAX_LEN - SUF_STR_LEN;
        }

        
public static void Main(String[] args)
        {

            
string str = "如果短信的长度超过70个字符,程序就会自动根据短信中的分隔符进行分割,在不是非常苛刻的情况下,它不会将一个词分成两段来发,比如,不会出现""你好""的前一个字在第一条短信内,而""好""字在第二条短信内!这都是在不增加短信数量的情况下优化的!";
            List
<String> ms = new MobileRegistService().StringSplit(str);
            
foreach (String m in ms)
            {
                Console.WriteLine(m 
+ "==>" + m.Length);
            }
        }

 

程序很简单,就不多说了,主要就是根据一些分隔符去分割。

posted on 2009-04-20 16:41  忘忧草2020  阅读(996)  评论(0编辑  收藏  举报