1. 设计一个函数 atoi(x),功能为将串 x 转换为整数,串 x 由0~9数字字符和表示负数的 “-” 符号组成,返回值为整型数值。
算法思路:设字符串存于字符数组 X 中,若转换后的数是负数,则字符串的第一个字符必为 '-' 。转换过程如下:将取出的数字字符减去字符零 '0' 的ASCII值,变成数;先前取出的数乘上10加上本次转换的数形成部分结果;如此一个字符一个字符地转换,直到字符串结束,得到结果。
long atoi(char * X)
{
long num = 0; // 结果整数初始化
int i = 1; // i为数组下标
if(X == NULL)
{
cout << "Pointer is NULL\n";
return 0;
}
if(X[0] != '-')
num = X[0]-'0'; // 如是正数,x[0]是数字字符
while(X[i] != '\0') // 当字符串未到尾,进行数的转换
num = 10*num + (X[i++] - '0'); // 先前取出的数乘上10加上本次转换的数形成部分结果
if(X[0] == '-')
return(-num); // 返回负数
else
return(num); // 返回正数
}
2. 编写算法,对给定的串str,返回其最长重复子串及其下标位置。例如,str = "abcdacdac",子串"cdac"是str的最长重复子串,下标为2。
我们把这个过程分为两步
第一步:求重复子串的长度
int rptSubLen(char * p, char * q)
{
int len = 0;
while(*p && *q)
{
if( *p == *q )
{
++len;
p++,q++;
}
else
break;
}
return len;
}
第二步:求最长重复子串
void longestRepeatSub(char *arr, int size, int &maxLen, int &maxIndex)
{
int i, j, len;
maxLen = 0; // 记录最长重复子串的长度
maxIndex = -1; // 记录最长重复子串的下标
for(i = 0; i < size; ++i)
{
for(j = i+1; j < size; ++j)
{
len = rptSubLen(&arr[i], &arr[j]);
if(len > maxLen)
{
maxLen = len;
maxIndex = i;
}
}
}
if(maxLen == 0)
return;
i = maxIndex;
cout << "The longest repeat substring:";
while(maxLen--)
cout << arr[i++];
cout << endl;
}
3. 假设采用串顺序存储结构,编写算法实现串的置换操作 replace(int pos, int num, const String &t),其含义是将当前串中从第pos个字符开始的num个字符用串 t 替换。
String & String::replace(int pos, int num, const String &t)
{
String temp(*this);
int i=0, j=0;
if(pos<1 || num<0) // 参数错误
{
return *this;
}
curLen += t.curLen-j;
delete []str;
str = new char[curLen+1];
assert(str != '\0');
while(i < pos-1) // 拷贝原串前pos-1个元素
str[i] = temp.str[i++];
while(j < t.curLen) // 拷贝t串
str[i++] = t.str[j++];
j = pos + num - 1;
while(temp.str[j] != '\0') // 拷贝原串从第pos+num个到串尾的元素
str[i++] = temp.str[j++];
str[i] = '\0';
return *this;
}
4. 写一个递归算法来实现串的逆序存储,要求不另设串存储空间。
void InvertStore(char A[]) // 字符串逆序存储的递归算法
{
char ch;
static int i = 0; // 使用静态变量
scanf ("%c",&ch);
if (ch != '.') // '.'表示字符串输入结束
{
InvertStore(A);
A[i++] = ch; // 字符串逆序存储
}
A[i] = '\0'; // 字符串结尾标记
}
5. 输入一个串,内有数字和非数字字符,如:"ak123x456 17960?302gef4563",将其中连续的数字作为一个整体,依次存放到数组 a 中,例如,123 放入 a[0] 中,456 放入 a[1] 中……编写算法统计其共有多少个整数,并输出这些整数。
int CountInt()
{
char ch;
int i=0,a[ ]; // 整数存储到数组a,i记录整数个数
scanf("%c",&ch); // 从左到右读入字符串
while(ch! = '#') // '#'是字符串结束标记
if(ch >= '0' && ch <= '9') // 是数字字符
{
num = 0; // 数初始化
while(ch >= '0' && ch <= '9') // 拼数
{
num = num * 10 + 'ch' - '0';
scanf("%c",&ch);
}
a[i++] = num;
if(ch != '#')// 若拼数中输入了'#',则不再输入
scanf("%c",&ch);
}
else
scanf("%c",&ch); // 输入非数字且非#时,继续输入字符
printf("共有%d个整数,它们是:",i);
for(j=0;j<i;j++)
{
printf("%6d",a[j]);
if((j+1)% 10 == 0)
printf("\n");
} // 每10个数输出在一行上
}
6. “回文串”是一个正读和反读都一样的串。例如,“level”和“noon”就是回文串,而“abc”和“aab”不是回文串。编写算法判断给定串是否为回文串。
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
int main()
{
string arr;
int i, j, k = 0;
while(getline(cin, arr))
{
if(arr == "STOP")
break;
k++;
for(i=0,j=arr.length()-1; i<j; i++,j--)
{
if(arr[i] != arr[j])
break;
}
if(i >= j)
cout << "#" << k << ": YES" << endl;
else
cout << "#" << k << ": NO" << endl;
}
return 0;
}