《算法与数据结构 (C++语言版)》算法设计题目总结——串

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;
}

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值