linux期末实训-算法题

6.

思路:编写函数指针,遍历每个字符,当遇到大写字母(A-Z的范围),将ASCII码减去32,得到小写字母的ASCII码,转换成小写字母

#include <stdio.h>
int main()
{
    char s[100]; int i;
    printf("输入字符串:\n");
   fgets(s,100,stdin);
    for (i = 0; s[i]; i++)
        if (s[i] >= 'A' && s[i] <= 'Z') s[i] += 32;
    else if (s[i] >= 'a' && s[i] <= 'z') s[i] -= 32;
    puts(s);
}

7.

编写函数指针,遍历每一个单词的第一个字符,当遇到小写字母(a-z的范围),将ASCII码加上32,得到大写字母的ASCII码,其余的字符不变。

#include <stdio.h>
#include <string.h>
int main() {
    printf("请输入你要转换的字符");
    char str[100];
    fgets(str,100,stdin);
    if (str[0] > 96 && str[0] < 123)
        str[0] = (char)(str[0] - 32);
    for (int i = 1; i < strlen(str) - 1; i++)
    {
        if (str[i] == 32 && str[i + 1] > 96 && str[i + 1] < 123)
            str[i + 1] = (char)(str[i + 1] - 32);
    }
    printf("%s", str);
    return 0;
}

8.

思路:采用空格统计单词的方法:空格出现的次数(连续的若干个空格作为出现一次空格;一行开头的空格不统计在内)决定单词个数。

#include <stdio.h>
int main(){
	int count = 0;
	char temp;
	int letter = 0;
	printf("Input words:");
	temp = getchar();
	while (temp != '\n'){
		if ((letter == 1) && (temp == ' ')){
			letter = 0}
		else if ((temp >= 'a' && temp <= 'z') || (temp >= 'A' && temp <= 'Z') || (temp >= '0' && temp <= '9'))
		{
			if (letter == 0){
				letter = 1;
				count++;
			}
		}temp = getchar();
	}
	printf("count: %d\n", count);
	return 0;
}

9.

思路:对字符串进行完整的遍历,如果出现空格则将i+1的值赋给i;并继续遍历,以此类推知道遍历结束

#include <stdio.h>
#include <string.h>
char* Remove(char* s){
	if (s == NULL){
		return NULL;
	}
	char* ps = s;
	int Ni = 0;
	int PreS = 1;
	int i = 0;
	while (ps[i] != '\0'){
		if (ps[i] != ' '){
			ps[Ni++] = ps[i];
			PreS = 0;
		}
		else if (ps[i] == ' ' && PreS == 0){
			ps[Ni++] = ps[i];
			PreS = 1;
		}
		i++;
	}
	Ni--;
	if (ps[Ni] == ' '){
		ps[Ni] = '\0';
	}
	else{
		ps[Ni + 1] = '\0';
	}
	return s;
}
int str9(){
	char s[200];
	getchar();
	fgets(s,200,stdin);
	char* temp = Remove(s);
	printf("%s\n\n", temp);

	return 0;
}
int main() {
	str9();
}

10

思路:进行一次遍历,如果i-1为空并且i不为空且在a到z的ascll码之间则输出i,其余继续遍历,如果遍历第一个字母的时候为空,则将下一个不为空的字母赋给第一个字母

#include <string.h>
#include <stdio.h>
void strfindwords()
{
	char s1[100];
	char s2[100];
	char s3[100];
	int t = 0;
	fgets(s1,100,stdin);
	s2[0] = s1[0];
	int num = strlen(s1);
	int num2 = 1;
	for (int i = 1; i < num; i++) {
		if (s1[i] == 32) {
			s2[num2] = s1[i + 1];
			num2++;
		}
	}
	for (int j = 0; j < num2; j++) {
		if (s2[j] != 32) {
			s3[t] = s2[j];
			t++;
		}
	}
	for (int j = 0; j < t + 1; j++)
	{
		printf("%c", s3[j]);
		// puts(s3);
	}
}
int str10()
{

	strfindwords();
	getchar();
	return 0;
}
int main() {
	str10();
}

21

对一串输入进去的字符串进行遍历查找,如果查找到字串则输出他的其实字符的位置,没有则输出没有

#include<stdio.h>
#include<string.h>
int main()
{
    int num = -1;
    char str[1000];
    char str1[1000];
    while (fgets(str1,1000,stdin)) {
        fgets(str,1000,stdin);
        int n = 0;
        if (strstr(str1, str) == NULL)
        {
            printf("%3d\n", num);
        }
        else
        {
            while (strstr(str1 + n, str) != NULL)
            {
                char* p = strstr(str1 + n, str);
                char c = *p;
                *p = '\0';
                printf("%3d", strlen(str1));
                n = strlen(str1);
                *p = c;
                n++;
            }
            printf("\n");
        }
    }
    return 0;
}

22

输入一串数字构成的字符串,从第一个开始遍历到结束,把每一个遍历到的字符进行相加运算并输出

#include <stdio.h>
#include <string.h>
int getchars(char arr[]); 
int main()
{
	char arr[20];
	printf("请输入一串字符串:");
	fgets(arr,20,stdin);
	printf("%d", getchars(arr));
}
int getchars(char arr[])
{
	int i;
	int sum = 0;
	for (i = 0; i < strlen(arr); i++)
	{
		if (arr[i] >= '1' && arr[i] <= '9')
		{
			sum += arr[i] - 48;
		}
	}
	return sum;
}

23

#include<stdio.h>
#include<stdlib.h>
int main(void)
{
	char price[] = "12345";
    printf("字符串:12345\n");
	const char *ptr = price;
	int intNum = 0;
	while(*ptr)
	{
		intNum *=10;
        intNum += *ptr - '0';
		ptr++;
	}
	printf("intNum=%d",intNum);
	return 0;
}

25

输入两串字符串,定义两个指针变量,指向的内存地址中存放的内容,用循环和判断语句判断内容是否相等,相等则继续比较,不相等,回退后继续比较,比较完子串,完全相等时,返回true,不完全相等时返回false。

#include <stdio.h>
#include <string.h>
int  str(char *s1, char*s2)
{
	char *p1 = s1, *p2 = s2;
	while (*p1)
	{
		if (*p1 == *p2)
		{
			while (*p1&&*p2)
			{
				if (*p1 == *p2)
				{
					p1++;
					p2++;
				}
				else
				{
					p1 = p1 - (p2 - s2) + 1;
					p2 = s2;
					break;
				}
			}
			if (!*p2)
			{
				return 1;
			}
		}
		p1++;
	}
	return 0;
}
 int str25()
{
	char s1[100], s2[100];
	printf("Input 2 strings:\n");
	scanf("%s", &s1);
	scanf("%s", &s2);
	str(s1, s2);
	if (str(s1, s2)==1)
	{
		printf("TRUE\n");
	}
	else
	{
		printf("FALSE\n");
	}
}
 int main() {
	 str25();
 }

直接插入排序

思路:插入排序的基本方法是:每一步将一个待排序的元素,按其排序码的大小,插入到前面已经排好序的一组元素的适当位置上去,直到元素全部插入为止,直接插入排序的时间复杂度为O(n^2)。

#include <stdio.h>
void Swap(int* a, int* b){
	int temp = *a;
	*a = *b;
	*b = temp;
}
void InsertSort_Up(int* arr, int length){
	 int i;
	for (i = 1; i < length; i++){
		int temp = arr[i];
		int j;
		for (j = i - 1; j >= 0 && arr[j] > temp; j--){
			arr[j + 1] = arr[j];
		}
		arr[j + 1] = temp;
	}
	return;
}
void InsertSort_Down(int* arr, int length){
     int i;
	for (i = 1; i < length; i++){
		int temp = arr[i];
		int j;
		for (j = i - 1; j >= 0 && arr[j] < temp; j--){
			arr[j + 1] = arr[j];
		}
		arr[j + 1] = temp;
	}
	return;
}
void PrintArr(int* arr, int length){
    int i;
	for ( i = 0; i < length; i++){
		printf("%d ", arr[i]);
	}
	printf("\n");
	return;
} 
int main( ){
    int a[] = {3, 5, 2, 1, 9, 0, 6, 4, 7, 8};
    int length = sizeof(a) / sizeof(a[0]);
    InsertSort_Up(a, length);
    PrintArr(a, length);
    InsertSort_Down(a, length);
    PrintArr(a, length);
    return 0;
}

希尔排序

希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着真想的逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件就被分到一组,算法终止,最坏情况下的时间复杂度为O(n²)。

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

void shellSort(int *a, int len); 

int main(void)
{
    int i, len, * a;
    printf("请输入要排的数的个数:");
    scanf("%d",&len);
    a = (int *)malloc(len * sizeof(int)); 
    printf("请输入要排的数:\n");
    for (i = 0; i < len; i++) { 
        scanf("%d",&a[i]);
    }   
    shellSort(a, len); 
    printf("希尔升序排列后结果为:\n");
    for (i = 0; i < len; i++) {
        printf("%d\t",a[i]);
    }
    printf("\n");

    return 0;
}

void shellSort(int *a, int len)
{
    int i, j, k, tmp, gap; 
    for (gap = len / 2; gap > 0; gap /= 2) {  
    	for (i = 0; i < gap; ++i) {
	        for (j = i + gap; j < len; j += gap) { 
	            tmp = a[j]; 
	            k = j - gap; 
	            while (k >= 0 && a[k] > tmp) {
	                a[k + gap] = a[k];
	                k -= gap;
	            }
	            a[k + gap] = tmp; 
	        }
	    }
    }
}

快排(kali)

思路:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,以此达到整个数据变成有序序列,时间复杂度:O(nlogn)空间复杂度:Θ(\lgn)。

#include<stdio.h>
void kuaipai(int a[], int start, int end)   
{
    int i, j, temp, x;
    i = start;
    j = end;
    x = a[start];   
    while (i < j)
    {
        while (i < j && x < a[j])   
            j--;
        while (i<j && x>a[i])   
            i++;
        if (i < j)  
        {
            temp = a[j];
            a[j] = a[i];
            a[i] = temp;
        }
    }
    temp = x;
    x = a[i];
    a[i] = temp;
    if (start < j) 
        kuaipai(a, start, j - 1);
    if (i < end)
        kuaipai(a, j + 1, end);
}
void print(int s[], int n)
{
    int i;
    for (i = 0; i < n; i++)
        printf("%d ", s[i]);
    printf("\n");
}

int main()
{
    int a[] = { 6,1,2,8,4,9,5,3 };
    print(a, 8);  
    kuaipai(a, 0, 7);  
    print(a, 8);  
}

acm7(kali)

从键盘输入一个四位数,将各个位的数加上5再模10,最后将第一位第四位互换、第二位与第三位互换输出。

#include<stdio.h>
int addm(int t)
{
	int a, b, c, d, a1, b1, c1, d1, t1;
	a = t / 1000;
	b = t / 100 % 10;
	c = t / 10 % 10;
	d = t % 10;
	a1 = (a + 5) % 10;
	b1 = (b + 5) % 10;
	c1 = (c + 5) % 10;
	d1 = (d + 5) % 10;
	t1 = d1 * 1000 + c1 * 100 + b1 * 10 + a1;
	return t1;
}
int jiem(int t)
{
	int a, b, c, d, a1, b1, c1, d1, t1;
	a = t / 1000;
	b = t / 100 % 10;
	c = t / 10 % 10;
	d = t % 10;
	a1 = (a - 5) % 10;
	b1 = (b - 5) % 10;
	c1 = (c - 5) % 10;
	d1 = (d - 5) % 10;
	t1 = d1 * 1000 + c1 * 100 + b1 * 10 + a1;
	return t1;
}
int main()
{
	int n;
	scanf("%d", &n);
	int n1 = addm(n);
	printf("加密前为:%d\n", n);
	int n2 = addm(n1);
	printf("加密后为:%d", n1);
	return 0;
}

acm8(kali)

思路:每个人有去和不去的两种可能,用0代表不去,1代表去,若有多个,按字母递增顺序排序。

#include<stdio.h>
int P[7] = { 0 };
void BiAdd(void)
{//模拟二进制的增一
    int i;
    P[1]++;
    for (i = 1; i <= 6; i++)
    {
        if (P[i] > 1) {
            P[i] = 0;
            P[i + 1]++;
        }
    }
}
int CountPerson(void)
{//统计派出了多少人
    int n = 0, i;
    for (i = 1; i <= 6; i++)
        if (P[i])    n++;
    return n;
}
int main()
{
    int a[7] = { 0 }, max = 0, t = 0, i, j;
    for (i = 1; i <= 64; i++)
    {
        t = 0;
        if (i != 1)    BiAdd();
        if ((P[1] + P[2] > 0) && (P[1] + P[4] < 2) && (P[1] + P[5] + P[6] == 2) && (P[2] == P[3]) && (P[3] != P[4])) {
            if (P[4] == 0)
                if (P[5] == 0)		t = CountPerson();
                else    t = CountPerson();
        }
        if (t > max) {
            max = t;
            for (j = 1; j <= 6; j++)   a[j] = P[j];
        }
    }
    for (i = 1; i <= 6; i++)
        if (a[i])    printf("%c,", 'A' + i - 1);
    return 0;
}

acm9(kali)

思路:先对每一位数进行遍历和判断,若大于零则记录并求和,若下一次的和大于此次的值则赋给前一个和的值

#include<stdio.h> 
int find(int *p,int n)
{
	int max=0,temp=0;
	int i;
 
	for(i=0;i<n;i++)
	{
		if(temp<=0)
			temp=p[i];
		else 
			temp+=p[i];
		if(max<temp)
			max=temp;
	}
	return max;
}
 
 
 
void main()
{
	int ar[]={1,-2,6,4,-7,3,2,5,-8,5,2};
	int n=sizeof(ar)/sizeof(*ar);
	printf("1 -2 6 4 -7 3 2 5 -8 5 2 \n");
	printf("%d\n",find(ar,n));
 
}

acm10(kali)

1用两个指针p、q来实现,p、q都指向链表开始位置,先让p指针向后走k个位置,然后两个指针同步走,当p指针为空的时候,q指针就是倒数第k个节点

#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>

typedef int Elemtype;

typedef struct LNode
{
    Elemtype data;
    struct  LNode *next;
} LNode,*LinkList;




LinkList List_TailInsert(LinkList L)
{
    int x;
    L=(LinkList)malloc(sizeof(LinkList));//创建头节点
    L->next=NULL;

    LNode *r=L,*s;
    scanf("%d",&x);
    while(x!=9999)
    {
        s=(LNode*)malloc(sizeof(LNode*));
        s->data=x;
        r->next=s;
        r=s;
        scanf("%d",&x);
    }
    r->next=NULL; //使环化
    return L;
}



void PrintLinkList(LinkList L)
{
    printf("打印链表\n");
    LNode *r=L->next;
    while(r!=NULL)
    {
        printf("%d--->",r->data);
        r=r->next;
    }
    printf("\n");
}


int Search_k(LinkList L,int k)
{
    LNode *p=L->next,*q=L->next;
    int count=0;
    while(p!=NULL)
    {
        if(count<k)count++;//p提前移动
        else q=q->next;
        p=p->next;
    }
    if(count<k)return 0;
    else
    {
        printf("%d",q->data);
        return 1;
    }
}

int main()
{

    LinkList L;//头指针,创建链表
    printf("创建链表,输入链表的值 9999表示结束!\n");
    L=List_TailInsert(L);
    printf("需要查找倒数第几个位置:");
    int k;
    scanf("%d",&k);
    Search_k(L,k);

    return 0;
}

2

#include <stdio.h>
#include<stdlib.h> 
 
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
 
#define MAXSIZE 20
 
typedef int Status;
typedef int ElemType;
 
typedef struct Node
{
 ElemType data;
 struct Node *next;
}Node;
typedef struct Node *LinkList;
 
Status InitList(LinkList *L)
{
	*L=(LinkList)malloc(sizeof(Node));
	if(!(*L))
		return ERROR;
	(*L)->next=NULL;
}
 
int ListLength(LinkList L)
{
	int i=0;
	LinkList p=L->next;
	while(p)
	{
		++i;
		p=p->next;
	}
	return i;
}
 
Status ListInsert(LinkList *L,int n,ElemType e)
{
 int j;
 LinkList p,s;
 p=*L;
 j=1;
 while(p&&j<n)
 {
	 p=p->next;
	 ++j;
 }
 if(!p||j>n)
	 return ERROR;
 s=(LinkList)malloc(sizeof(Node));
 s->data=e;
 s->next=p->next;
 p->next=s;
  return OK;
}
Node*  FindElem(LinkList *L,int k)
{
	LinkList  ptr1, ptr2;
	ptr1=ptr2=*L;
   	if(k>ListLength(*L))
	{
		printf("输入的要查找的倒数元素太大!");
	    exit(0);
		
	}
	for(int i=0;i<k;i++)
	{
		ptr1=ptr1->next;
	}
	
    while(ptr1!=NULL)
	{
		ptr1=ptr1->next;
		ptr2=ptr2->next;
	}
	return ptr2; 
}
int main()
{
	LinkList L;
	ElemType e;
	Status i;
	int j,len;
	i=InitList(&L);
    printf("初始化L后:ListLength(L)=%d\n",ListLength(L));
	
	for(j=0;j<10;j++)
		i=ListInsert(&L,j,j);
     printf("在L的表头依次插入1~10后:L.data=");
	 LinkList p;
      p=L->next;
	  while(p)
	  {
		  printf("%d ",p->data);
		  p=p->next;
	  }
	   printf("\n");
	  Node* q;
	  q=FindElem(&L,4);
	  printf("倒数第4个元素为:%d\n",q->data);
	return 0;
}

acm12(kali)

思路:定义一个长度为10个数组,依次遍历这个数组,记录每个数值出现的次数,超过数组长度一半的则输出。

#include <stdio.h>
#include <assert.h>
int find_half(int *arr, int len)
{
	int count = 0;
	int cur = 0;
	int i = 0;
	assert(arr != NULL);
	for (; i < len; ++i)
	{
		if (count == 0)
		{
			cur = arr[i];
			count = 1;
		}
		else if (arr[i] == cur)
			count++;
		else
			count--;
	}
	return cur;
}
 
int main()
{
	int arr[] = { 1, 2, 2, 2, 3, 2, 6, 2, 7, 2 };
    printf("数组的为\n");
    printf("1 2 2 2 3 2 6 2 7 2\n");
	int len = sizeof(arr) / sizeof(arr[0]);
	printf("%d\n", find_half(arr, len));
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值