CarceerCup 系列 第一章 Arrays and strings

本文提供了一系列字符串操作算法的实现,包括判断字符串是否具有唯一字符、反转C风格字符串、去除字符串中的重复字符、判断两个字符串是否为回文、替换字符串中的空格、矩阵旋转以及判断一个字符串是否为另一个字符串的旋转。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

翻译和代码有不正之处,欢迎批评指正。有好的想法,欢迎交流。

1、Implement an algorithm to determine if a string has all unique characters. What if you can not use additional data structures?

问题描述:

设计一个算法,判断一个字符串是否含有重复的字符,不能使用额外的数据结构。

思路:

排序,判断是否重复。

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

void QuickSort(char *p, int n);
int StrightWay(char *);
int main()
{
	int n;
	char *p;
	int i = 0;
	int temp;
	char *ptemp;
	char c;
	printf("Input n\n");
	scanf("%d", &n);
	if(n <= 0)
	{
		printf("Input Error\n");
		return 1;
	}
	p = (char*)malloc(sizeof(char) * (n+1));
	if(p == NULL)
	{
		printf("Out of space\n");
		return 1;
	}
	getchar();
	ptemp = p;
	temp = n;
	printf("Input the string\n");
	while(((c = getchar()) != EOF) && temp)
	{
		*ptemp++ = c;
		temp--;
	}
	*ptemp = '\0';
//	printf("%s", p);
	QuickSort(p, n);
	if(!StrightWay(p))
		printf("It's unique\n");
	else
		printf("It's not unique\n");
	free(p);
	return 0;
}

void QuickSort(char *p, int n)
{
	void Swap(char *, char *);
	void Find(char *, char *, char *);
	char temp;
	int i, j;
	if(n < 2)
		return;
	j = n>>1;
	i = -1;
	Find(p, p+j, p+n-1);
	Swap(p+j, p+n-1);
	for(j = 0; j < n-1; j++)
	{
		if(p[j] < p[n-1])
		{
			++i;
		   if(i != j)
		   {
			  Swap(p+i, p+j);
		   }
		}
	}
	++i;
	Swap(p+i, p+n-1);
	QuickSort(p, i);
	QuickSort(p+i+1, n-i-1);
}

void Swap(char *p, char *q)
{
	char c;
	c = *p;
	*p= *q;
	*q = c;
}

int StrightWay(char *p)
{
	int i, j;
	if(p == NULL)
		return 1;
	for(i = 0, j = 1; (p[i] != p[j]) && (p[j] != '\0'); i++, j++)
		;
	if(p[j] == '\0' && p[i+1] == '\0')
		return 0;
	else
		return 1;
}

void Find(char *a, char *b, char *c)
{
	if(*a > *b)
		Swap(a, b);
	if(*a > *c)
		Swap(a,c);
	if(*b > *c)
		Swap(b, c);
}


2、Write code to reverse a C-Style String. (C-String means that “abcd” is represented as five characters, including the null character.)

问题描述:

写代码倒置一个c风格的字符串。

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

void Reverse(char *p);
void Swap(char *, char *);

int main()
{
	char p[100] = "abcdefg";
	Reverse(p);
	printf("%s\n", p);
	return 0;
}

void Reverse(char *p)
{
	int i, j;
	if(p == NULL)
		return;
	i = 0; 
	j = strlen(p) - 1;
	while(i < j)
	{
		Swap(p+i, p+ j);
		i++;
		j--;
	}
}

void Swap(char *p, char *a)
{
	char c;
	c = *p;
	*p = *a;
	*a = c;
}


3、Design an algorithm and write code to remove the duplicate characters in a string without using any additional buffer. NOTE: One or two additional variables are fine. An extra copy of the array is not

问题描述:

设计一个算法,移除一个字符串中重复的字符,不要使用额外的缓存,一个或者两个变量时可以的。

思路:

排序,设置两个指针。

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

char *Remove(char *);
void Qsort(char *, int n);
int main()
{
	char p[100] = "333333222222";
	int n = strlen(p);
	if(n < 2)
		return 0;
	Qsort(p, n);
//	printf("%s\n", p);
	printf("%s", Remove(p));
}

char *Remove(char *p)
{
	void Move(char *, char *);
	char *first, *second;
	if(p == NULL)
		return NULL;
	first = p;
	second = first + 1;
	while(*second != '\0')
	{
		if(*first != *second)
		{
			first++;
			second++;
		}
		else
		{
			while(*second == *first)
				second++;
			Move(second, first+1);
			second = first+1;
		}
	}
	return p;
}

void Move(char *second, char *first)
{
	if(!(first && second))
		return;
	while(*second)
		*first++ = *second++;
	*first = '\0';
}

void Qsort(char *p, int n)
{
	void Swap(char *, char *);
	int i, j;
	j = 1;
	i = 0;
	if(n < 2)
		return;
	for(; j < n; j++)
	{
		if(p[j] < p[0])
		{
			i++;
			if(i != j)
				Swap(p+i, p+j);
		}
	}
	Swap(p, p+i);
	Qsort(p, i);
	Qsort(p+i+1, n-i-1);
}

void Swap(char *p, char *q)
{
	char c;
	c = *p;
	*p = *q;
	*q = c;
}


4、Write a method to decide if two strings are anagrams or not

问题描述:

判断两个字符串是否是回文的。

思路:

用一个256个元素的数组统计第一个字符串中每个出现的次数

#include<stdio.h>

int anagrams(char*, char *);
int main()
{
	char a[100] = "abcd";
	char b[100] = "adbce";
	if(anagrams(a, b))
	{
		printf("YES\n");
	}
	else
		printf("NO\n");
}

int anagrams(char *a, char *b)
{
	int Arr[256];
	int i = 0;
	for(i = 0; i < 256; ++i)
		Arr[i] = 0;
	while(*a != '\0')
	{
		Arr[*a]++;
		a++;
	}
	while(*b != 0)
	{
		Arr[*b]--;
		if(Arr[*b] < 0)
			return 0;
		b++;
	}
	for(i = 0; i < 256; ++i)
		if(Arr[i] != 0)
			return 0;
	if(i == 256)
		return 1;
}


5、Write a method to replace all spaces in a string with ‘%20’.

问题描述:

把一个字符串中的空格用 %20替换。

思路:

先遍历一字符串,统计有多少个空格,然后从后往前复制替换。

#include<stdio.h>

char * Replace(char *);
int main()
{
	char p[100] = "    ";
	printf("%s", Replace(p));
}

char* Replace(char *p)
{
	int count;
	char *q, *temp;
	if(p == NULL)
		return NULL;
	count = 0;
	q = p;
	while(*q != '\0')
	{
		if(*q == ' ')
			count++;
		q++;
	}
	temp = q+ 2* count;
	while(q >= p)
	{
		if(*q == ' ')
		{
			*temp-- = '0';
			*temp-- = '2';
			*temp = '%';
		}
		else
			*temp = *q;
		temp--;
		q--;
	}
	return p;
}


6、Given an image represented by an NxN matrix, where each pixel in the image is 4 bytes, write a method to rotate the image by 90 degrees. Can you do this in place?

问题描述:

把一个数字顺时针旋转90度。

思路:

方法:按层,依次把每个元素放到合适的位置。

代码如下:

#include<stdio.h>
#include<malloc.h>

void Rotate(int n,	int**p);
int main()
{
	int n;
	int **p;
	int i, j;
	printf("Input n \n");
	scanf("%d", &n);
	p = (int **)malloc(sizeof(int*));
	if(p == NULL)
		return 0;
	for(i = 0; i < n; ++i)
	{
		p[i] = (int *)malloc(sizeof(int) * n);
		if(p[i] == NULL)
			return 0;
	}
	printf("Input value n*n\n");
	for(i = 0; i < n; i++)
		for(j = 0; j < n; j++)
			scanf("%d", *(p+i) + j);
	Rotate(n, p);
	printf("out value\n");
	for(i = 0; i < n; i++)
	{
		for(j = 0; j < n; j++)
			printf("%d ", p[i][j]);
		printf("\n");
	}
	return 0;
}

void Rotate(int n, int **a)
{
	int layer;
	int last;
	int first;
	int offset;
	int i;
	int temp;
	for(layer = 0; layer < n/2; layer++)
	{
		first = layer;
		last = n-1 - layer;
		for(i = first; i < last; ++i)
		{
			offset = i - first;
			temp = a[first][i];
			a[first][i] = a[last-offset][first];
			a[last-offset][first] = a[last][last-offset];
			a[last][last-offset] = a[i][last];
			a[i][last] = temp;
		}
	}
}

7、Write an algorithm such that if an element in an MxN matrix is 0, its entire row and column is set to 0.

问题描述:

如果一个数组中有元素的值为零,则把所在行和列都设为0.

思路:

遍历并保存值为0的元素的行号和列号。然后置为0;

代码如下:

#include<stdio.h>
#include<malloc.h>
#include<assert.h>

void Zero(int n, int **p);
int main()
{
	int n;
	int **p;
	int i, j;
	printf("Input n \n");
	scanf("%d", &n);
	assert(n > 0);
	p = (int **)malloc(sizeof(int*));
	if(p == NULL)
		return 0;
	for(i = 0; i < n; ++i)
	{
		p[i] = (int *)malloc(sizeof(int) * n);
		if(p[i] == NULL)
			return 0;
	}
	printf("Input value n*n\n");
	for(i = 0; i < n; i++)
		for(j = 0; j < n; j++)
			scanf("%d", *(p+i) + j);
	Zero(n, p);
	printf("out value\n");
	for(i = 0; i < n; i++)
	{
		for(j = 0; j < n; j++)
			printf("%d ", p[i][j]);
		printf("\n");
	}
	for(i = 0; i < n; ++i)
	    free(p[i]);
	p == NULL;
	return 0;
}

void Zero(int n, int **p)
{
	int *column;//lie
	int *line;//hang;
	int i, j;
	column = (int *)malloc(sizeof(int) * n);
	for(i = 0; i < n; ++i)
		column[i] = 0;
	line = (int *)malloc(sizeof(int) * n);
	for(i = 0; i < n; ++i)
		line[i] =  0;
	for(i = 0; i < n; i++)
		for(j = 0; j < n; j++)
		{
			if(p[i][j] == 0)
			{
				column[j] = 1;
				line[i] = 1;
			}
		}
	for(i = 0; i < n; i++)
	{
		if(column[i] == 1)
		{
			for(j = 0; j < n; j++)
				if(p[j][i] != 0)
					p[j][i] = 0;
		}
	}

	for(i = 0; i < n; i++)
		if(line[i] == 1)
		{
			for(j = 0; j < n; j++)
				if(p[i][j]!= 0)
				p[i][j] = 0;
		}
	free(line);
	free(column);
	line = NULL;
	column = NULL;
}


8、Assume you have a method isSubstring which checks if one word is a substring of another. Given two strings, s1 and s2, write code to check if s2 is a rotation of s1 using only one call to isSubstring (i.e., “waterbottle” is a rotation of “erbottlewat”).

问题描述:

判断一个字符串是不是另外一个的旋转字串。

思路:

构造'waterbottlewaterbottle'判断erbottlewat是不是构造的字符串的字串。

代码如下:

#include<stdio.h>
#include<string.h>
bool Isrotation(char *, char *);
int main()
{
	char p[100] = "waterbottle";
	char q[50] = "erbottlewat";
	if(strlen(p) != strlen(q))
		return 0;
	if(Isrotation(p, q))
		printf("YES\n");
	else
		printf("NO\n");
	return 0;
}

bool Isrotation(char *p, char *q)
{
	int str(char *p, char *q);
	void copy(char *);
	int i;
	
	if(!(p&&q))
	{
		printf("Error\n");
		return false;
	}
	copy(p);
	printf("%s\n", p);
	p[strlen(p)] = '\0';
	i = str(p, q);
	if(i == 1)
		return true;
	else
		return false;
}

int str(char *p, char *q)
{
	int i, j, k;
	int lenp, lenq;
	if(!(p&&q))
	{
		printf("Error\n");
		return 0;
	}
	lenp = strlen(p);
	lenq = strlen(q);
	for(i = 0; i < lenp-lenq+1; ++i)
	{
		for(j = 0,k = i; q[j]!= '\0' && (p[k] == q[j]); k++, j++)
			;
		if(q[j] == '\0')
			break;
	}
	if(q[j] == '\0' && i < lenp-lenq+1)
		return 1;
	else
		return 0;
}

void copy(char *p)
{
	char *temp;
	char *ptr;
	ptr = temp = p;
	while(*temp)
		temp++;
    p = temp;
	while(ptr < p)
	{
		*temp++ = *ptr++;
	}
	*temp = '\0';
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值