您的位置:首页 > 理论基础 > 数据结构算法

程序员代码面试指南:IT名企算法与数据结构题目最优解-字符串问题:C/C++语言实现

2015-10-24 10:43 1356 查看

程序员代码面试指南-字符串问题:C/C++语言实现

以下程序运行环境:VC6++

看到左老师出的书:程序员代码面试指南:IT名企算法与数据结构题目最优解,都是Java实现,为了刷题,但是职位是C/C++,以下是我用C/C++实现的代码
题目介绍略简单,以后补上

/*

//程序员代码面试指南-字符串问题

//1.判断两个字符串是否互为变形词

bool isDeformation(string str1,string str2)
{
if(str1.length() !=str1.length())
return false;
const char *chas1=str1.c_str();
const char *chas2=str2.c_str();
int *map = new int[256];//字符的ASC在0-255之间
for(int i=0;i<str1.length();i++)
map[chas1[i]]++;//字符对应的asc码值所在的数组数值++
for(int j=0;j<str2.length();j++)
if(map[chas2[j]]-- == 0)//先判断再--
return false;
return true;
}
int main()
{
string str1,str2;
getline(cin,str1);
getline(cin,str2);
(isDeformation(str1,str2)==true)? cout<<"yes\n" : cout<<"no\n" ;
return 0;
}


*/

/*

//2.字符串中数字子串的求和:给定一个字符串,求其中全部数字串所代表的数字之和

//eg:a1cd-2ef33  ==1-2+33=21
int numSum(string str)
{
const char *str1=str.c_str();
int num=0;//提取出的当前数字
int sum=0;//最后的和
int cur=0;//当前数值
bool posi=true;
for(int i=0;i<str.length();i++)
{
cur=str1[i]-'0';//转换为数字
if(cur<0 || cur>9)//不是数字
{
sum+=num;//不是数字后计算和
num=0;
if(str1[i] == '-')
{
if(i-1>-1 && str1[i-1]=='-')//如果前一个也是-则取反
posi=!posi;
else
posi=false;
}
else posi=true;//+
}
else
{
num=num*10+((posi)? cur : -cur );
}
}
sum+=num;//当最后一个字符是数字的话在这里加上,因为sum是在不为数字时候计算的
return sum;
}
int main()
{
string str;
getline(cin,str);
cout<<numSum(str);
}


*/

/*

//3.去掉字符串中连续出现K个0的子串
string removeKZeros(string str,int k)
{
char *str1=new char[str.length()];
strcpy(str1,str.c_str());
int start=-1,count=0;
for(int i=0;i<str.length();i++)
{
if(str1[i]=='0')
{
count++;
start=((start==-1)? i:start);
}
else
{
if(count==k)
while(count--!=0)
str1[start++]=0;
count=0;
start=-1;
}
}
if(count==k)//如果最后一个字符是0的情况
while(count--!=0)
str1[start++]=0;
return str=str1;
}
int main()
{
string str;
int k;
cin>>k;
cin.ignore();//不忽略剩余的回车会导致getline无效
getline(cin,str);//输入两个回车是因为VC6的bug
cout<<removeKZeros(str,3);
return 0;
}


*/

/*

//4.判断两个字符串是否互为旋转词:思路:在b+b中看是否包含a
bool isRotation(string a,string b)
{
if(a.length()!=b.length())
return false;
string b2=b+b;
return strstr(b2.c_str(),a.c_str())!=NULL;
}
int main()
{
string a,b;
getline(cin,a);
getline(cin,b);
isRotation(a,b)? cout<<"yes"<<endl : cout<<"no"<<endl;
return 0;
}


*/

/*

//5.将整数字符串转成整数值:符合日常形式eg"012"不符合,32位不能溢出

//判断是否符合日常形式函数
bool isValid(const char chas[],int len)
{
if(chas[0] !='-' && (chas[0]<'0' || chas[0]>'9'))//首位不是-和数字不符合
return false;
if(chas[0]=='-' && (len==1 || chas[1]=='0'))
return false;
if(chas[0]=='0' && len>1)
return false;
for(int i=0;i<len;i++)
if(chas[i]<'0' || chas[i]>'9')
return false;
return true;
}
//转换函数
int convert(string str)
{
const char* chas=str.c_str();
if(isValid(chas,str.length())!=true)//不符合
return 0;
bool posi= chas[0]=='-'? false:true;
int minq=-(2147483648/10);//下面计算中如果还小于此数就是溢出了
int minr=-(2147483648%10);//如果等于上数后且余数小于次数就是溢出了,因为都是负数所以才是小于
int res=0;
int cur=0;
for(int i=0;i<str.length();i++)
{
cur='0'-chas[i];//负数
if(res<minq || (res==minq && cur<minr))
return 0;
res=res*10+cur;
}
if(posi && res==-2147483648)//整数最大是2147483647
return 0;
return posi? -res:res;
}
int main()
{
string str;
getline(cin,str);
cout<<convert(str);
return 0;
}


*/

/*

//6.替换字符串,将str中from替换为to  eg:str=123abc  from=abc  to=4567  返回1234567   str=123abcabc  from=abc to=x 返回123x:只有一个x注意

//想法:将原字符串中from字符替换为0,然后碰到0的地方str相加
string replace(string str,string from,string to)
{
char *str1=new char[str.length()+1];
strcpy(str1,str.c_str());
const char *from1=from.c_str();
int match=0;
for(int i=0;i<str.length();i++)//查找from后添0
{
if(str1[i]==from1[match++])
{
if(match==from.length())//是from
while(match)
{
str1[i-match+1]=0;;
match--;
}
}
else
{
match=0;
}
}
string res="";
string cur="";
for(int j=0;j<str.length();j++)//在0的地方补to
{
if(str1[j]!=0)
cur+=str1[j];//一个个的排起来
if(str1[j]==0 && (j==0 || str1[j-1]!=0))
{
res+=cur+to;
cur="";
}
}
if(cur.c_str()!="")
res+=cur;//最后一部分
delete[] str1;
return res;
}
int main()
{
string str,from,to;
getline(cin,str);
getline(cin,from);
getline(cin,to);
cout<<replace(str,from,to);
return 0;
}


*/

/*

//7.统计字符串eg:aaabbadddffc   a_3_b_2_a_1_d_3_f_2_c_1
#include <sstream>//字符串流,作字符串int转换用的
string getCountString(string str)
{
const char *str1=str.c_str();
string res="";
res+=str1[0];//char转string直接赋值
stringstream ss;
string tmp;
int num=1;
for(int i=1;i<str.length();i++)
{
if(str1[i]!=str1[i-1])
{
ss.clear();
ss<<num;//int转字符串
ss>>tmp;
res+="_"+tmp+"_"+str1[i];
num=1;
}
else
num++;
}
ss.clear();
ss<<num;
ss>>tmp;
return res+="_"+tmp;
}
int main()
{
string str;
getline(cin,str);
cout<<getCountString(str);
return 0;
}


*/

/*

//8.给定一个index返回上题统计字符串中第index个原始字符eg:a_1_b_100  index=50 返回b
char getCharAt(string str,int index)
{
const char *str1=str.c_str();
bool stage=true;//当前在遍历字符还是数字标志,true字符
int num=0,sum=0;
char cur;
for(int i=0;i<str.length();i++)
{
if(str1[i]=='_')
stage=!stage;
else if(stage)
{
sum+=num;
if(sum>index)
return cur;
num=0;
cur=str1[i];
}
else num=num*10+str1[i]-'0';
}
return sum+num>index ? cur:0;
}
int main()
{
string str;
int index;
cin>>index;
cin.ignore();
getline(cin,str);
cout<<getCharAt(str,index);
return 0;
}


*/

/*

//9.判断字符数组中是否所有的字符都只出现过一次,未规定空间复杂度
bool isUniquel(const char *buf,int len)
{
bool map[256]={0};
for(int i=0;i<len;i++)
{
if(map[buf[i]])
{
cout<<map[buf[i]];
return false;
}
map[buf[i]]=true;
}
return true;
}
int main()
{
string str;
getline(cin,str);
isUniquel(str.c_str(),str.length())==true ? cout<<"true" : cout<<"false";
return 0;
}


*/

/*

//10.上题中要求空间复杂度为O(1)时间复杂度尽量低

//思路:排序后查找是否大于1,关键在与排序算法的选择,堆排序 O(1)空间,时间O(nlogn)
void HeapAdjust(char a[],int s,int n)
{
//调整为小根堆,从小到大
int rc=a[s];
for(int j=2*s;j<=n;j*=2)
{
if(j<n && a[j]>a[j+1])//判断左右子数大小
j++;
if(rc<=a[j])
break;
a[s]=a[j];
s=j;
}
a[s]=rc;
}
//第一步:建初堆
void CreatHeap(char a[],int n)
{
//小根堆
for(int i=n/2;i>0;i--)
HeapAdjust(a,i,n);
}
//整合
void HeapSort(char a[],int n)
{
CreatHeap(a,n);//第一步,建立初堆
for(int i=n;i>1;i--)
{
int x=a[1];//堆顶与最后一个元素互换
a[1]=a[i];
a[i]=x;
HeapAdjust(a,1,i-1);
}

}
//查找方法
bool isUnique2(char a[],int n)
{
//调用排序算法
HeapSort(a,n);
for(int i=1;i<n;i++)
if(a[i]==a[i-1])
return false;
return true;
}
int main()
{
string str;
getline(cin,str);
char *a=new char[str.length()+1];
strcpy(a,str.c_str());
cout<<(isUnique2(a,str.length())==true ? "true":"false");
delete[] a;
return 0;
}


*/

/*

//11.在从小到大排序但含有null的字符串中查找字符串出现的位置,eg:{a,null,b,c,null,d,c..}中查找c出现最左的位置3

//思路:二分查找,因为是已经有序的了

//下面程序其实不对了:下面意思是从排序但含有空格的字符串中查找字符出现的位置 (空格和NULL不是一回事,空格是' 'asc=32,null是指针其值为0,结束符是'\0'ASC=0)

//所以真正的程序这里应该用字符串数组
int getIndex(string str,char c)
{
int res=-1;
int left=0;
int right=str.length()-1;
int mid=0;
int i=0;
const char *buf=str.c_str();
while(left<=right)
{
mid=(left+right)/2;
if(buf[mid]!=' ')
{
if(buf[mid]==c)//正好就是,不一定是最左,还要在左侧找
{
res=mid;
right=mid-1;
}
else if(buf[mid]<c)//在右侧
left=mid+1;
else right=mid-1;  //在左侧
}
else
{
i=mid;
while(str[i]==' ' && --i>=left);//依次向左找
if(i<left || str[i]<c)//如果左侧都是空或者左侧中的最右一个非空字符<c,则从右侧找
left=mid+1;
else //在左侧中
{
res=(str[i]==c? i:res);
right=i-1;
}
}

}
return res;

}
int main()
{
string str;
char c;
getline(cin,str);
cin>>c;
cout<<getIndex(str,c);
return 0;
}


*/

/*

//11.1字符串调整与替换:将空格替换为%20,注意空格是一字节,%20是三字节,数组不能越界

//思路:遍历一遍,看看数组中有多少个字符,多少个空格,然后重新计算替换后的数组长度,从右向左替换转换位置
void replace(char buf[])
{
int len=0;//buf多少字符
int num=0;//空格个数
int size=0;//替换后长度
for(len=0;buf[len]!='\0';len++)
if(buf[len]==' ')
num++;
size=len+2*num-1;
for(int i=len-1;i>=0;i--)
{
if(buf[i]!=' ')
buf[size--]=buf[i];
else {buf[size--]='0';buf[size--]='2';buf[size--]='%';}
}
}
int main()
{
string str;
getline(cin,str);
char *buf=new char[256];//这里用定长表示的足够大
strcpy(buf,str.c_str());
replace(buf);
cout<<buf;
delete[] buf;
return 0;
}


*/

/*

//11.2字符串调整与替换:字符只有数字和*,将所有*移到数字左侧,且不能改变数字之前顺序eg12**45   **1245

//思路:从右往左遍历,是数字就从右到左放,不怕将*覆盖了,没有数字了后将剩下的区域全部复制成*就好了,因为不是数字就是*
void modify(char buf[],int len)
{
int j=len-1;
for(int i=j;i>=0;i--)
{
if(buf[i]!='*')
buf[j--]=buf[i];
}
while(j>=0)
buf[j--]='*';
}
int main()
{
string str;
getline(cin,str);
char *buf=new char[str.length()+1];
strcpy(buf,str.c_str());
modify(buf,str.length());
cout<<buf;
delete[] buf;
return 0;
}


*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: