作业6——串

1. 串的基本操作
//AIxi
#include <stdio.h>
#include <string.h>

#define MAIN_STR_LEN 100
#define SUB_STR_LEN 20

int MyStrCompare(char* Str1, char* Str2) 
{ 
    int i;
    int result = 0;
    for (i = 1; (i <= Str1[0]) && (i <= Str2[0]); i++) 
    {
        if (Str1[i] > Str2[i]) 
        {
            result = 1;
            break;
        } 
        else if (Str1[i] < Str2[i]) 
        {
            result = -1;
            break;
        } 
    }
    if (result == 0) 
    {
        if (Str1[0] > Str2[0]) 
        {
            result = 1;
        } 
        else if (Str1[0] < Str2[0]) 
        {
            result = -1;
        } 
    } 
    return result;
}

int MySubStrIndex(char* MainStr , char* SubStr , int pos) 
{
    int i, j, result;
    if ((pos < 0) || (pos > (MainStr [0] - SubStr[0] + 1))) 
    {
        return 0;
    } 
    i = pos;
    j = 1;
    while (i <= MainStr [0] && j <= SubStr [0]) 
    {
        if (MainStr[i] == SubStr[j]) 
        {
            i++;
            j++;
        } 
        else 
        {
            i = i - j + 2;
            j = 1;
        }
    }
    if (j > SubStr [0]) 
    {
        result = i - SubStr [0];
    } 
    else 
    {
        result = 0;
    }
    return result;
}

char MyStrDelete(char* S, int pos , int len) 
{
    int i;
    if (pos < 1 || pos > S[0] - len + 1 || len < 0)
        return -1;
    for (i = pos + len; i <= S[0]; i++)
        S[i - len] = S[i];
    S[0] -= len;
    return 1;
}

char MyStrInsert(char* S, int pos , char* T) 
{
    int i;
    if (pos < 1 || pos > S[0] + 1)
        return -1;
    if (S[0] + T[0] <= MAIN_STR_LEN) 
    {
        for (i = S[0]; i >= pos; i--) 
        {
            S[i + T[0]] = S[i];
        }
        for (i = pos; i < pos + T[0]; i++) 
        {
            S[i] = T[i - pos + 1];
        }
        S[0] = S[0] + T[0];
        return 1;
    } 
    else 
    {
        for (i = MAIN_STR_LEN; i <= pos; i--) 
        {
            S[i] = S[i - T[0]];
        }
        for (i = pos; i < pos + T[0]; i++) 
        {
            S[i] = T[i - pos + 1];
        }
        S[0] = MAIN_STR_LEN;
        return 0;
    }
}

int MyStrAssign(char * StrTobeAssigned , char * StrInput)

{
    int len = strlen(StrInput);
    if (len > MAIN_STR_LEN)
        return -1;
    StrTobeAssigned[0] = len;
    strcpy(&StrTobeAssigned[1], StrInput);
    return 1;
}

int MyStrReplace(char * MainStr , char * SubStr1 , char * SubStr2)

{
    int i = 1, tot = 0;
    do 
    {
        i = MySubStrIndex(MainStr, SubStr1, i);
        if (i)
        {
            MyStrDelete(MainStr, i, SubStr1[0]);
            MyStrInsert(MainStr, i, SubStr2);
            i += strlen(SubStr2);
            tot++;
        }
    } while (i);
    return tot;
}

int main() 
{
    char MainStr[MAIN_STR_LEN + 1];
    char SubStr1[SUB_STR_LEN + 1];
    char SubStr2[SUB_STR_LEN + 1];
    int i;
    int compareResult;
    int pos;
    int replaceCounter = 0;
    char InputBuf[3][MAIN_STR_LEN + 1];

    printf("please input 3 strings as MainStr , SubStr1 and SubStr2\n");
    scanf("%s %s %s", InputBuf[0], InputBuf[1], InputBuf [2]);

    if (MyStrAssign(MainStr, InputBuf[0]) == -1 || MyStrAssign(SubStr1, InputBuf[1]) == -1 || MyStrAssign(SubStr2, InputBuf[2]) == -1)
    {
        printf("Error: String length exceeds maximum length\n");
        return -1;
    }

    printf("MainStr =:%d,", MainStr[0]);
    for (i = 1; i <= MainStr[0]; i++) 
    {
        printf("%c,", MainStr[i]);
    }
    printf("\n");
    printf("SubStr1 =:%d,", SubStr1[0]);
    for (i = 1; i <= SubStr1[0]; i++) 
    {
        printf("%c,", SubStr1[i]);
    }
    printf("\n");
    printf("SubStr2 =:%d,", SubStr2[0]);
    for (i = 1; i <= SubStr2[0]; i++) 
    {
        printf("%c,", SubStr2[i]);
    }
    printf("\n");

    compareResult = MyStrCompare(SubStr1, SubStr2);
    printf("SubStr1 compare with SubStr2 is %d\n", compareResult);

    pos = MySubStrIndex(MainStr, SubStr1, 1);
    printf("pos of SubStr1 in MainStr is %d\n", pos);

    pos = MySubStrIndex(MainStr, SubStr2, 1);
    printf("pos of SubStr2 in MainStr is %d\n", pos);

    replaceCounter = MyStrReplace(MainStr, SubStr1, SubStr2);
    printf("The content of MainStr after %d times of replacing SubStr1 with SubStr2 is :\n%d,", replaceCounter , MainStr[0]);
    for (i = 1; i <= MainStr[0]; i++) 
    {
        printf("%c,", MainStr[i]);
    }
    printf("\n");
    return 0;
}
2. 统计字符数
//自己写的代码

#include <stdio.h>
#include <string.h>

#define MAXSTRLEN 100
#define TRUE 1
#define FALSE 0
#define ERROR -1
#define OK 1

typedef char SString[MAXSTRLEN + 1];

void SStringAssign(SString S,char*str)
{
	int i = 1,len = 0;
	for(;str[len] != '\0';len ++)
	for(;str[i - 1] != '\0';i ++)
	{
		S[i] = str[i - 1];
	}
	S[0] = len;
	S[len + 1] = '\0'; 
}

void CountStr(SString S,int *total)
{
	int i = 1;
	for(;i <= S[0];i ++)
	{
		total[S[i] - 'a'] ++;
	}
}

void PrintMax(int *total)
{
	int max = total[0],i = 0,max_n = 0;
	for(;i < 26;i ++)
	{
		if(max < total[i])
		{
			max = total[i] ;
			max_n = i;
		}
	}
	printf("%c %d\n",max_n + 'a',max);
}

int main(int argc, char *argv[]) 
{
	int n ;
	scanf("%d",&n);
	getchar();
	while(n --)
	{
		SString S;
		char str[MAXSTRLEN + 1000];
		scanf("%s",str); 
        str[100] = '\0';
		getchar();
		//printf("%s",str); 
		SStringAssign(S,str);
		
		int total[26] = {0};
		CountStr(S,total);
		
		PrintMax(total);			
	} 
	return 0;
}
3.字符串连接
//自编代码

#include <stdio.h>
#include <string.h>
#define MAXSTRLEN 100
#define TRUE 1
#define FALSE 0
#define ERROR -1
#define OK 1

typedef char SString[MAXSTRLEN + 1];

void StrAssign(SString S,char*str)
{
	int i = 1;
	for(;str[i - 1] != '\0';i ++)
	{
		if(str[i - 1] == '#')	break;
		S[i] = str[i - 1];
	}
	S[0] = i;
	S[i + 1] = '\0';
}

int StrConcat(SString S, SString T) {
    if (S[0] + T[0] > MAXSTRLEN) {
        return ERROR;
    }
    int i = 1;
	for(;S[i] != '\0';i++)
	{
		T[T[0] + i] = S[i];
	}
    
    T[0] += S[0];

    return OK;
}

int main(int argc, char *argv[]) 
{
	int n = 1000,i;
	char str1[n],str2[n];

    // 读取两个字符串,以 '#' 结束
    scanf("%[^#]#", str1);
    getchar();  // 读取并丢弃换行符
    scanf("%[^#]#", str2);
   
    
	SString S,T;
	StrAssign(S,str1);
	StrAssign(T,str2);
	
	StrConcat(S,T);
	
	for(i = 1;i <= T[0];i ++)
	{
		printf("%c",T[i]);
	}
	printf("\n");
	return 0;
}
4. 词频统计
//AI跑得代码   
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MAX_WORD_LENGTH 50
#define HASH_SIZE 1000

// 定义单词节点结构体
typedef struct WordNode {
    char word[MAX_WORD_LENGTH];
    int count;
    struct WordNode* next;
} WordNode;

// 定义哈希表结构体
typedef struct {
    WordNode* buckets[HASH_SIZE];
} HashTable;

// 哈希函数,将单词转换为哈希值
int hash(char *word) {
    int hash = 0;
    while (*word) {
        hash = (hash * 31 + *word) % HASH_SIZE;
        word++;
    }
    return hash;
}

// 创建单词节点
WordNode* createWordNode(char *word) {
    WordNode* newNode = (WordNode*)malloc(sizeof(WordNode));
    if (newNode == NULL) {
        fprintf(stderr, "Memory allocation failed\n");
        exit(1);
    }
    strcpy(newNode->word, word);
    newNode->count = 1;
    newNode->next = NULL;
    return newNode;
}

// 在哈希表中查找单词节点,如果不存在则返回NULL
WordNode* findWord(HashTable* hashTable, char *word) {
    int index = hash(word);
    WordNode* current = hashTable->buckets[index];
    while (current != NULL) {
        if (strcmp(current->word, word) == 0) {
            return current;
        }
        current = current->next;
    }
    return NULL;
}

// 向哈希表中插入单词节点,如果已存在则增加计数,否则创建新节点插入
void insertWord(HashTable* hashTable, char *word) {
    int index = hash(word);
    WordNode* current = hashTable->buckets[index];
    WordNode* previous = NULL;
    while (current != NULL) {
        if (strcmp(current->word, word) == 0) {
            current->count++;
            return;
        }
        previous = current;
        current = current->next;
    }
    // 单词不存在,创建新节点插入
    WordNode* newNode = createWordNode(word);
    if (previous == NULL) {
        hashTable->buckets[index] = newNode;
    } else {
        previous->next = newNode;
    }
}

// 比较函数,用于qsort排序
int compare(const void *a, const void *b) {
    const WordNode *word1 = *(const WordNode **)a;
    const WordNode *word2 = *(const WordNode **)b;
    // 先比较出现次数,出现次数相同时按照字典序排序
    if (word1->count != word2->count) {
        return word2->count - word1->count;
    } else {
        return strcmp(word1->word, word2->word);
    }
}

// 释放哈希表
void freeHashTable(HashTable* hashTable) {
    for (int i = 0; i < HASH_SIZE; i++) {
        WordNode* current = hashTable->buckets[i];
        while (current != NULL) {
            WordNode* temp = current;
            current = current->next;
            free(temp);
        }
    }
    free(hashTable);
}

int main() {
    // 打开文件
    FILE *file = fopen("article.txt", "r");
    if (file == NULL) {
        fprintf(stderr, "Failed to open file\n");
        return 1;
    }

    // 创建哈希表
    HashTable* hashTable = (HashTable*)malloc(sizeof(HashTable));
    if (hashTable == NULL) {
        fprintf(stderr, "Memory allocation failed\n");
        return 1;
    }
    memset(hashTable->buckets, 0, sizeof(hashTable->buckets));

    char word[MAX_WORD_LENGTH];
    // 读取文件中的每个单词并进行统计
    while (fscanf(file, "%s", word) == 1) {
        // 转换为小写
        for (int i = 0; word[i]; i++) {
            word[i] = tolower(word[i]);
        }
        // 去除单词末尾的标点符号
        int len = strlen(word);
        while (len > 0 && ispunct(word[len - 1])) {
            word[len - 1] = '\0';
            len--;
        }
        // 插入哈希表
        insertWord(hashTable, word);
    }
    fclose(file);

    // 将哈希表中的单词节点存入数组
    WordNode* wordArray[HASH_SIZE];
    int count = 0;
    for (int i = 0; i < HASH_SIZE; i++) {
        WordNode* current = hashTable->buckets[i];
        while (current != NULL) {
            wordArray[count++] = current;
            current = current->next;
        }
    }

    // 对单词节点数组按照出现次数进行排序
    qsort(wordArray, count, sizeof(WordNode*), compare);

    // 输出前100个单词及其出现次数
    int numWords = count < 100 ? count : 100;
    for (int i = 0; i < numWords; i++) {
        printf("%s %d\n", wordArray[i]->word, wordArray[i]->count);
    }

    // 释放内存
    freeHashTable(hashTable);

    return 0;
}

5. 字符串中的第一个唯一字符
//我的代码
#include <stdio.h>
#include <string.h>

#define MAXSTRLEN 300000
#define TRUE 1
#define FALSE 0
#define ERROR -1
#define OK 1

typedef char SString [MAXSTRLEN + 1]; 

void StrAssign(SString S,char*str)
{
	int i = 1;
	for(;str[i - 1] != '\0';i ++)
	{
		S[i] = str[i - 1];
	}
	S[0] = i - 1;
	S[i] = '\0';
}

int Unique_Index(SString S)
{
	if(S[0] == 0)	return -1;
	int i,j,tag;
	for(i = 1;i <= S[0];i ++)
	{
		for(j = 1;j <= S[0];j ++)
		{
			tag = -1;
			if(j == i)	continue;	
			else if(S[i] == S[j])	break;
			if(S[i] != S[j])	tag = i;
		}
		if(tag != -1)	return i - 1;
	}
	return -1;
}

int main(int argc, char *argv[]) 
{
	char str[MAXSTRLEN + 1];
	scanf("%s",str);
	
	SString S;
	StrAssign(S,str);
	
	int a = Unique_Index(S);
	printf("%d",a); 
	
	return 0;
}
6. 求一个串中出现的第一个最长重复子串
#include <stdio.h>
#include <string.h>
#include<malloc.h>

#define MAXSTRLEN 255
#define TRUE 1
#define FALSE 0
#define ERROR -1
#define OK 1

int check(char *s, int x, int n,int *pos) 
{
	int j = 0,i,k;

	for(;j < n - x + 1;j ++)
	{
		char substr[x + 1];
		for(i = j,k=0;i < x + j; i ++,k++)
		{
			substr[k] = s[i];
		}
		substr[x] = '\0';
	    int count = 0;
		for (i = 0; i <= n - x; i++) 
		{
	        if (strncmp(s + i, substr, x) == 0) 
			{
	            count++;
	        }
	        if(count == 2)
	        {
	        	*pos = j;
	        	return 1;
			}
	    } 
	}
	return 0;
}

char *search_longest_repeated_substring(char *s, int n) {
    int l = 0, r = n,pos = 0;
    while (l < r) {
        int mid = l + (r - l + 1) / 2;
        if (check(s, mid, n, &pos))    l = mid;
        else      r = mid - 1;
    }
    if (l == 0) {
        return NULL;
    }
    char *result;
	result = (char*)malloc((l + 1) * sizeof(char));
    if (result == NULL) {
        printf("内存分配失败\n");
        return NULL;
    }
    strncpy(result, s + pos, l);
    result[l] = '\0';
    return result;
}

int main() {
    char *s = malloc(MAXSTRLEN * sizeof(char));
    if (s == NULL) 
	{
        printf("内存分配失败\n");
        return 1;
    }
    scanf("%s", s);

    char *result = search_longest_repeated_substring(s, strlen(s));
    
    if (result == NULL) 
	{
        printf("没有最长重复子串\n");
    }
	 else 
	 {
        printf("%s\n", result);
        free(result);
    }

    free(s);

    return 0;
}

7. Caesar密码
//AI	跑的代码
#include <stdio.h>
#include <string.h>

// 函数用于解密Caesar密码
void decrypt_caesar(char *cipher_text) {
    // 定义字母替换表
    char mapping[26] = {
        'V', 'W', 'X', 'Y', 'Z', 'A', 'B', 'C', 'D', 'E',
        'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
        'P', 'Q', 'R', 'S', 'T', 'U'
    };

    // 对密码消息中的每个字符进行解密
    for (int i = 0; cipher_text[i] != '\0'; i++) {
        // 如果是字母,则进行解密
        if (cipher_text[i] >= 'A' && cipher_text[i] <= 'Z') {
            cipher_text[i] = mapping[cipher_text[i] - 'A'];
        }
    }
}

int main() {
    char line[200];

    // 读取输入直到遇到ENDOFINPUT
    while (1) {
        scanf("%s", line);
        if (strcmp(line, "ENDOFINPUT") == 0) {
            break;
        }

        if (strcmp(line, "START") == 0) {
            getchar(); // 消耗掉换行符
            fgets(line, 200, stdin); // 读取密码消息
            decrypt_caesar(line); // 解密消息
            printf("%s", line); // 输出原始消息
        }
    }

    return 0;
}

8.判断等值子串
#include <stdio.h>
#include <string.h>

void longest_equal_substring(char *s) {
    int max_length = 0;
    char *max_substring = NULL;
    
    int current_length = 1,i;
    char *current_start = s;
    for ( i = 1; s[i] != '!'; i++) {
        if (s[i] == s[i - 1]) {
            current_length++;
        } else {
            if (current_length > max_length) {
                max_length = current_length;
                max_substring = current_start;
            }
            current_length = 1;
            current_start = s + i;
        }
    }
    
    // Check the last substring
    if (current_length > max_length) {
        max_length = current_length;
        max_substring = current_start;
    }

    if (max_length > 1) {
        for (i = 0; i < max_length; i++) {
            printf("%c", max_substring[i]);
        }
    } else {
        printf("no");
    }
}

int main() {
    char input_str[1000];
    scanf("%s", input_str);
    longest_equal_substring(input_str);
    return 0;
}

9.判断两个字符串是否匹配
//我的代码 + AI优化
#include <stdio.h>
#include <stdbool.h>

#define TRUE 1
#define FALSE 0

bool isMatch(char *str1, char *str2) {
    // 当两个字符串都为空时,它们是匹配的
    if (*str1 == '\0' && *str2 == '\0')
        return TRUE;
    
    // 当其中一个字符串为空时,另一个不为空,它们不匹配
    if (*str1 == '\0' || *str2 == '\0')
        return FALSE;

    // 如果当前字符匹配或者是 '?',则继续比较下一个字符
    if (*str1 == *str2 || *str2 == '?')
        return isMatch(str1 + 1, str2 + 1);

    // 如果遇到 '*',则递归地尝试所有可能的情况
    if (*str2 == '*') {
        // 将 '*' 后面的子串作为模式串
        char *pattern = str2 + 1;
        
		while(*pattern == '*')	
		{
			pattern ++; 
			str1++;
		}
		       
		if(*pattern == '\0')	return TRUE;
		
		while(*pattern == '?')
		{
			pattern++;
        	str1++;
        	
        	// 当两个字符串都为空时,它们是匹配的
   			if (*str1 == '\0' && *pattern == '\0')
        		return TRUE;
        		
        	// 当其中一个字符串为空时,另一个不为空,它们不匹配
    		if (*str1 == '\0' || *str2 == '\0')
        		return FALSE;
		}
		

		
        // 在 str1 中查找所有可能的匹配
        while (*str1 != '\0') {
            if (isMatch(str1, pattern))
                return TRUE;
            str1++;
        }

        // 如果在 str1 中没有找到匹配,则返回 FALSE
        return FALSE;
    }

    // 如果当前字符不匹配,且不是通配符,则说明不匹配
    return FALSE;
}


int main() {
    char str1[1000], str2[1000];

    // 读取两个字符串,以 '#' 结束
    scanf("%[^#]#", str1);
    getchar();  // 读取并丢弃换行符
    scanf("%[^#]#", str2);
    
    // 调用匹配函数进行匹配
    if (isMatch(str2, str1)) {
        printf("yes\n");
    } else {
        printf("no\n");
    }

    return 0;
}
  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值