C语言编程题

1、递归

汉诺塔是由三根杆子A,B,C组成的。A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。
要求按下列规则将所有圆盘移至C杆:每次只能移动一个圆盘;大盘不能叠在小盘上面。
提示:可将圆盘临时置于B杆,也可将从A杆移出的圆盘重新移回A杆,但都必须尊循上述两条规则。问:如何移?

void MoveHanoi(int iCnt, char* pSrc, char* pMid, char* pDest)
{
    if (iCnt == 1)
    {
        printf(" %s->%s\n", pSrc, pDest);    //当iCnt只有1个的时候直接从src移动到dest
    }
    else
    {
        MoveHanoi(iCnt - 1, pSrc, pDest, pMid);            //将src上iCnt-1个通过dest移动到mid
        printf(" %s->%s\n", pSrc, pDest);//将src上最后一个移动到dest
        MoveHanoi(iCnt - 1, pMid, pSrc, pDest);            //将mid上iCnt-1个通过src移动到dest
    }
}

有一对刚出生的小兔子,两个月后会生一对小兔子,以后每个月又要生一对小兔子。在没有死亡的情况下,问第n个月后总共有多少对兔子?
实际上每个月兔子的对数是一个斐波那契数列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55……

unsigned RabitBirth(unsigned uMounths)
{
    if (uMounths <= 1)
        return 1;
    else
        return RabitBirth(uMounths - 1) + RabitBirth(uMounths - 2);
}

//判断一个数组是否为递增

bool JudgeIncre(int ary[], unsigned uSize)//uSize>=2
{
    if (uSize == 2)
    {
        return ary[1] > ary[0];
    }
    else
    {
        if (ary[uSize - 1] >= ary[uSize - 2])
            return JudgeIncre(ary, uSize - 1);
        else
            return false;
    }
}

2、排序

快速排序,思想:分区 + 对分好的区进行递归操作
分区就是从数组中取出一个数,然后以这个数为轴心,将所有小于这个数的数放到其左边,将所有大于这个数的数放到其右边.
对这个数组分区完成之后再分别对左边、右边区域进行分区,递归结束后排序完成.

void swap(int *a, int *b)
{
    int  tmp = *a;
    *a = *b;
    *b = tmp;
}

//对ary进行分区:以ary[0]为轴心数,将比轴心数小的和大的分别放到其左右两侧,返回轴心数左边数字个数
int partition(int *ary, int iLen)
{
    const int iPivotPos = 0;//以ary[0]为轴心数
    int iPivotNum = ary[iPivotPos];//轴心数
    int iLeftLen = 0;//保存比轴心数小的数字个数
    swap(&ary[iPivotPos], &ary[iLen - 1]);//将轴心数放置最右侧

    //将所有的数与轴心数对比,如果比轴心数小的话就往左边顺序排放
    for (int i = 0; i < iLen-1; i++)
    {
        if (ary[i] < iPivotNum)
        {
            if(ary[i] != ary[iLeftLen])
                swap(&ary[i], &ary[iLeftLen]);
            iLeftLen++;
        }
    }

    //将轴心数从最右侧放置轴心位置
    if(iLeftLen != iLen - 1)
        swap(&ary[iLeftLen], &ary[iLen - 1]);

    return iLeftLen;
}

void quick_sort(int *ary, int iLen)
{
    //个数为0或1终止递归
    if (iLen == 1 || iLen == 0)
        return;

    //对ary进行分区:将比ary[0]小的和大的分别放到其两侧
    int iLeftLen = partition(ary, iLen);

    //对两侧的区域再进行分区
    quick_sort(ary, iLeftLen);
    iLeftLen++;//加上轴心数
    if (iLeftLen != iLen)
        quick_sort(&ary[iLeftLen], iLen - iLeftLen);
}

冒泡法排序:将十个数里边最大(小)的放到右边(两两比较,将大(小)的换到右边),.......,将两个数里边最大(小)的放到右边(两两比较,将大(小)的换到右边)

void bubble_sort(int* ary, int iLen, bool bIncreaseOrder = true)
{
    for (int i = 0; i < iLen - 1; i++)
    {
        for (int j = 0; j < iLen- 1 - i; j++)
        {
            if (bIncreaseOrder)
            {
                if (ary[j] > ary[j + 1])
                    swap(&ary[j], &ary[j + 1]);
            }
            else
            {
                if (ary[j] < ary[j + 1])
                    swap(&ary[j], &ary[j + 1]);
            }
        }
    }
}

选择法排序:将十个数里边最小(大)的放到左边(遍历右边9个数获得最小(大)数的索引,将找到的最小(最大)数换到第一个数),.......,将两个数里边最小(大)的放到左边(遍历右边1个数获得最小(大)数的索引,将找到的最小(最大)数换到第九个数)

void select_sort(int* ary, int iLen, bool bIncreaseOrder = true)
{
    for (int i = 0; i < iLen - 1; i++)
    {
        int iLargeIndex = i;
        for (int j = i+1; j < iLen; j++)
        {
            if (bIncreaseOrder)
            {
                if (ary[j] < ary[iLargeIndex])
                    iLargeIndex = j;
            }
            else
            {
                if (ary[j] > ary[iLargeIndex])
                    iLargeIndex = j;
            }
        }

        if (iLargeIndex != i)
            swap(&ary[i], &ary[iLargeIndex]);
    }
}

3、字符串处理

实现字符串处理strstr():
对pStr逐字与pSubStr比较,eg:
A B C D E F
C D
pStr中第一个就不同,跳过第一个不再考虑

A B C D E F
C D
pStr中第二个也不同,跳过第二个不再考虑

A B C D E F
C D
pStr中有相同的,进行处理

char* MyStrstr(char* pStr, char* pSubStr)
{
    //assert(pStr && pSubStr);

    char*pStrAdvance = pStr;
    while (*pStrAdvance)
    {
        char* p = pStrAdvance, *q = pSubStr;
        while (*p && *q)
        {
            if (*p == *q)
            {
                p++;
                q++;
            }
            else
                break;
        }
        if (!*q)
            return pStrAdvance;

        pStrAdvance++;
    }

    return NULL;
}

4、链表问题

//链表节点结构
typedef struct node
{
    int iIndex;
    struct node* pNext;
}Node, *NodePtr;

//创建链表
NodePtr CreateList(unsigned iLen)
{
    NodePtr pHeadNode = NULL, pLastNode = NULL;
    for (unsigned i = 0; i < iLen; i++)
    {
        NodePtr pNode = new Node;
        pNode->iIndex = i;
        if (pLastNode)
            pLastNode->pNext = pNode;
        else
            pHeadNode = pNode;

        pLastNode = pNode;
    }
    pLastNode->pNext = NULL;

    return pHeadNode;
}

//输出链表
void PrintList(NodePtr pHeadNode)
{
    NodePtr pNode = pHeadNode;
    do
    {
        cout << pNode->iIndex << ", ";
        pNode = pNode->pNext;
    } while (pNode);

    cout << endl;
}

//链表逆序:定义三个节点指针分别指向前三个节点,第二个节点的pNext重新指向第一个节点,三个节点指针再往后移动,如此往复
NodePtr TurnList(NodePtr pHeadNode)
{
    if (pHeadNode->pNext)
    {
        NodePtr pLastNode = pHeadNode;
        NodePtr pNode = pLastNode->pNext;
        NodePtr pNextNode = pNode->pNext;

        while (pNextNode)
        {
            pNode->pNext = pLastNode;

            pLastNode = pNode;
            pNode = pNextNode;
            pNextNode = pNextNode->pNext;
        }

        pNode->pNext = pLastNode;
        pHeadNode->pNext = NULL;

        return pNode;
    }
    else
        return pHeadNode;
}

//链表排序:利用选择排序法思想
void SelectSortList(NodePtr pHeadNode)
{
    NodePtr pNode = pHeadNode;
    while (pNode->pNext)
    {
        NodePtr pNodeMin = pNode;
        NodePtr pNodeNext = pNode->pNext;
        while (pNodeNext)
        {
            if (pNodeNext->iIndex < pNodeMin->iIndex)
                pNodeMin = pNodeNext;

            pNodeNext = pNodeNext->pNext;
        }

        if (pNodeMin != pNode)
            swap(&pNode->iIndex, &pNodeMin->iIndex);

        pNode = pNode->pNext;
    }
}

//合并两个有序链表为一个
NodePtr UnionList(NodePtr pHeadNode1, NodePtr pHeadNode2)
{
    NodePtr pHeadNode = new Node;//新的链表添加一个头结点
    NodePtr pNode1 = pHeadNode1, pNode2 = pHeadNode2, pNode = pHeadNode;

    while (pNode1 && pNode2)
    {
        if (pNode1->iIndex <= pNode2->iIndex)
        {
            pNode->pNext = pNode1;
            pNode = pNode->pNext;
            pNode1 = pNode1->pNext;
        }
        else
        {
            pNode->pNext = pNode2;
            pNode = pNode->pNext;
            pNode2 = pNode2->pNext;
        }
    }

    pNode->pNext = pNode1 ? pNode1 : pNode2;//插入剩余段

    NodePtr pReturnNode = pHeadNode->pNext;
    delete pHeadNode;//删除新链表的头结点
    return pReturnNode;
}
时间: 2024-11-10 15:24:37

C语言编程题的相关文章

一道有意思的C语言编程题

最近在看经典的C语言入门书籍K&R,虽然是一本入门书籍,可是其中的精妙之处却需要慢慢体会.其中的经典题很多,仔细琢磨一定会收获良多. 今天看到这样一道题:编写一个删除C语言程序中所有的注释语句.感觉颇有意思,与大家一起分享一下: 我的思路: 找到注释的起始符号 \ 判断紧接着的输入字符,如果是*或者是\,则说明后面全是注释,跳过即可,否则照样输出 其他则直接输出 疑问: 所配套的答案书中提出要考虑引号后面的内容以做出响应,不是很明白这是为什么.个人认为无需考虑引号的影响也能将注释去除,希望有高手

2018.3 江苏省计算机等级考试 C语言 编程题答案

题目要求:给定一个数字范围,输出满足这些条件: 1.能被3整除: 2.包含数字5, 将满足的数字放在特定的数组里输出.输出这些数里5出现的个数.数字的个数. 想起来有点伤心,本来很简单的题,考试的时候程序写错一行,结果成了死循环,最后还没找出来错,下来以后才想起来.以后必须长点心. 代码: #include<stdio.h>int flag(int x0,int x1,int b[],int *p);int main(){int i,intnumber,fivenumber;//数字的个数.5

C语言编程题002

给出两个整数,L和R,其中L<=A<=B<=R,然后求出A^B值最大的数.其中1<=L<=R<=1000. 比如说L = 1;R = 3; L 0001 R 0011 LR中间还有 0010,其中的最大值是0001 ^ 0010 = 0011;输出就是2. 写出一个函数计算这个数: 我写了一个,但是没通过最终测试,只有12分,总分20分,不知道哪里还需要改进? 1 #include <stdio.h> 2 #include <string.h>

C语言编程题001

有一颗树,一年两个生长周期,春天它长高一倍,夏天长高1m,问N个周期后树有多高?假设从春天开始树高为1m,第0个周期树高为1m. 要求:1.可以同时输入多个生长周期 如:3//表示下面有几个生长周期 0 1 4 输出结果为:1 2 7 不知道写的对不对,大家看一下啊 1 #include <stdio.h> 2 #include <string.h> 3 #include <math.h> 4 #include <stdlib.h> 5 6 int main

程序设计入门—Java语言 第六周编程题 1 单词长度(4分)

第六周编程题 依照学术诚信条款,我保证此作业是本人独立完成的. 1 单词长度(4分) 题目内容: 你的程序要读入一行文本,其中以空格分隔为若干个单词,以'.'结束.你要输出这行文本中每个单词的长度.这里的单词与语言无关,可以包括各种符号,比如"it's"算一个单词,长度为4.注意,行中可能出现连续的空格. 输入格式: 输入在一行中给出一行文本,以'.'结束,结尾的句号不能计算在最后一个单词的长度内. 输出格式: 在一行中输出这行文本对应的单词的长度,每个长度之间以空格隔开,行末没有最后

中国MOOC_面向对象程序设计——Java语言_期末考试编程题_1细胞自动机

期末考试编程题 返回 这是期末考试的编程题 温馨提示: 1.本次考试属于Online Judge题目,提交后由系统即时判分. 2.学生可以在考试截止时间之前提交答案,系统将取其中的最高分作为最终成绩. 1 细胞自动机(30分) 题目内容: 这是细胞自动机的非图形版本.细胞自动机是指在一个二维网格内,每一个网格是一个细胞.每个细胞有活和死两种状态. 初始时刻,有些细胞是活的,有些细胞是死的.自动机的每一步,根据每个细胞周围8个格子内的其他细胞的生存情况决定这个细胞下一步是否存活.具体的规则如下:

中国MOOC_零基础学Java语言_期末考试的编程题_1二进制的前导的零

期末考试的编程题 返回 这是期末考试的编程题,在60分钟内,你可以多次提交,直到正确为止. 温馨提示: 1.本次考试属于Online Judge题目,提交后由系统即时判分. 2.学生可以在考试截止时间之前提交答案,系统将取其中的最高分作为最终成绩. 1 二进制的前导的零(10分) 题目内容: 计算机内部用二进制来表达所有的值.一个十进制的数字,比如18,在一个32位的计算机内部被表达为00000000000000000000000000011000.可以看到,从左边数过来,在第一个1之前,有27

C语言程序设计进阶 第1周编程题

第1周编程题 查看帮助 返回 依照学术诚信条款,我保证此作业是本人独立完成的. 温馨提示: 1.本次作业属于Online Judge题目,提交后由系统即时判分. 2.学生可以在作业截止时间之前不限次数提交答案,系统将取其中的最高分作为最终成绩. 1 字符串比对(10分) 题目内容: 题目说起来很简单,你会读到两个字符串,每个字符串占据一行,每个字符串的长度均小于10000字符,而且第一个字符串的长度小于第二个字符串的.你的程序要找出第一个字符串在第二个字符串中出现的位置,输出这些位置,如果找不到

JavaScript编程题(含腾讯2016校招题)

作者:ManfredHu 链接:http://www.manfredhu.com/2016/04/02/15-veryGoodForUsing/ 声明:版权所有,转载请保留本段信息,否则请不要转载 几道觉得挺有意思的编程题,感觉做下来,自己对一些新方法的看法有了新的变化. 比如indexOf,reduce,Array.isArray,forEach这些方法,以前一看到兼容性是IE9+就有点害怕,项目中不敢用,导致后面越来越陌生,不过现在一想的话.其实只要用Polyfill或者提前fix掉就可以了