关于字符串处理,以及模拟高精度、大数运算的几小经验



最近两次acm培训赛都遇到了类似题目,其实这类题目的共同做法是通过字符数组或字符串模拟操作,再加上我之前做在线Office之类的东西时没少和字符串打交道,所以就总结出几点小经验来,拿出来分享。
     另外我的个人博客开通,主要会写一些技术性文章,地址 http://blog.sunfangweb.cn , 如果这个地址访问不了可以用 www.rtswhp.org.cn/blog/?usrt=sfccni 来访问。本文章在博客同步发表。

      言归正传,首先看看字符串的拆分,这是很重要的一点,重点在于判断好分隔的符号与分隔后各块的存储方式。以在线Office中的例子为例,把一串类似“A87D8-8988-EEFF76-2331-ADDF6G,23133323,976556,223441,25256741.......”等的字符串分开,使“23133323”类似的项存在数组里,一下是代码:

//ActionScript3代码:
var tempstr:String=xnshareserv.lastResult.friends_getAppUsers_response.uid+".";

//在字符串皆为加入符号,作为循环终止的判断,注意应该加入原本不可能出现的符号
      var tempstr2:String="";
      var i:int=0,j:int=0,k:int=0;
      var count:int=1;   //计数器1,用于做数组下标
      Debug.inspect(xnshareserv.lastResult);
      while(tempstr.charAt(i)!=".") {//判断结束
       while(tempstr.charCodeAt(i)!=44) {//判断“,”分隔符
          //Debug.trace("i:"+i);
          //Debug.trace("char:"+tempstr.charAt(i));
          tempstr2=tempstr2.concat(tempstr.charAt(i));//将两个","间字符遍历复制
          i++;
          if(tempstr.charAt(i)==".") break;
         }
         if(tempstr.charAt(i)==".") break;
         //Debug.trace("tempstr2:"+tempstr2);
         if(count==1) {
          ;   //头一个段不加
         }else{
       temparr.push(tempstr2);    //加入每段数据到数组
         } 
         tempstr2="";   //清空临时的数据段
         i++;
         count++;
       }



      案例二,大数加法,实质是用字符数组人工模拟加法。

题目要求是进行1000位数以内的加法,显然超long long int的范围了......



//C代码:

//大数加法
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char res[1001]={'0'};  //结果集
char na[1001]={'0'};  //运算的a
char nb[1001]={'0'};  //运算的b
char ia[1001]={'0'};  //输入的a与b,要在处理后变成na,nb
char ib[1001]={'0'};
void cplus(char * a,char * b) {   //进行大数相加
 int la,lb=0;
 int i=0;
 int rest=0;  //临时变量,用于进行每位的存放
 for(i=0;i<1001;i++) {
  rest=((int)(*(a-i)-48)+(int)(*(b-i)-48));   //每位的加法,注意减去48的"0"的ascii码
  if(rest>=10){
   rest-=10;   //进位处理
   res[1000-i-1]+=1;
  }
  res[1000-i]+=rest;
 }
}
void prep() {   //准备函数,把ia,ib搞成na,nb,区别是处理时向数组尾对齐
 int i=0;
 while (strlen(ia)-i!=0)
 {
  na[1000-i]=ia[strlen(ia)-i-1];
  i++;
 }
 i=0;
 while (strlen(ib)-i!=0)
 {
  nb[1000-i]=ib[strlen(ib)-i-1];
  i++;
 }
}
void print() {   //输出结果
 int i=0,j=0;
 while (res[i]=='0')
 {
  i++;
 }
 while (i+j<1001)
 {
  printf("%c",res[i+j]);
  j++;
 }
}
int main() {
 memset(res,'0',1001);
 memset(na,'0',1001);
 memset(nb,'0',1001);
 memset(ia,'0',1001);
 memset(ib,'0',1001);
 scanf("%s %s",ia,ib);
 prep();
 cplus(&na[1000],&nb[1000]);
 print();
 system("PAUSE");
 return 0;
}



       案例三:高精度乘方。

//C++代码:

//B题:求幂
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <string>

using namespace std;


void multiply(string & a, string & b);
string powit(string & number,int n);


int main()
{
 
 string number;
 int n;
 while (cin>>number>>n){
  cout << powit(number,n) << endl;
 }
 //system("pause");
 return 0;
}


void multiply(string & a, string & b)
{
 int i=0,j=0,k=0;
 string result;
 result.resize(a.length() + b.length());
 for (i=0;i<result.length();i++)
  result[i]=0;   //result存储时是从结果的最低位存储的,进位就可以往后进了
 for (i = 0; i < a.length(); i++ )
 {                                
  for (j = 0, k = 0; j < b.length(); j++ )
  {
   int l = (int)(a[ a.length() - i - 1 ]-'0') * int(b[b.length()- j - 1]-'0') + k; 
   result[i+j] += l;
   k = result[i+j] / 10;
   result[i+j] = result[i+j] % 10;
  }
  if(k!=0)  result[i+j] = k;   // 进位处理
 }
 a.clear();     //清空,用来处理下边的东东
 for(i = result.length()-1; i>0 && result[i] == 0; i-- )
  result.erase(i, 1);                 
 for (i = 1; i <= result.length(); i++ )
  a.push_back(result[result.length()-i] + '0');
}

string powit(string & number,int n) {
 int i, posi = 0;
 for (i = 0; i < number.length(); ++i )
  if (number[i] == '.')
   break;
 posi = number.length() - i - 1;    
 number.erase(i, 1);                
 string result2("1");
 for (i = 0; i < n; ++i)
  multiply(result2, number);           
 if (posi != -1)    
  posi *= n;       //小数点的判断

 while ( (int)result2.length() < posi )            
  result2.insert(result2.begin(), '0');

 if (posi != -1)
 {
  result2.insert(result2.end() - posi, '.'); 
  for (i = result2.length() - 1; i > 1 && result2[i] == '0'; i-- )  ;                          
  result2.erase(i + 1);
  if (result2[i] == '.')  result2.erase(i);    //干掉多余的0    

 }
 return result2;
}

你可能感兴趣的:(REST,Blog,J#,Office)