C语言的一点复习

都忘光了,拿来复习一小下

运行环境Win7 VS2010

题目是某年和某年华为的某几道上机题目,题目不去找了。

【第一个】

就是实现一个方法,将链表倒序。

#include "stdafx.h"
#include<iostream>

typedef struct tagListNode{
    int value;
    struct tagListNode *next;
}ListNode;

void converse(ListNode **head){
    ListNode *currentNode = *head;
    ListNode *privNode = NULL;
    ListNode *nextNode = NULL;
    while(currentNode!=NULL){
        nextNode = (*currentNode).next;
        (*currentNode).next = privNode;
        privNode = currentNode;
        currentNode = nextNode;
    }
    *head = privNode;
}

void PrintList(ListNode **head){
    ListNode *currentNode = *head;
    while(currentNode!=NULL){
        printf_s("%d",(*currentNode).value);
        currentNode = (*currentNode).next;
    }
    printf_s("\n");
}
void main(){
    ListNode *head;
    ListNode *body1;
    ListNode *body2;
    ListNode *tail;
    head = (ListNode *)malloc(sizeof(ListNode));
    body1 = (ListNode *)malloc(sizeof(ListNode));
    body2 = (ListNode *)malloc(sizeof(ListNode));
    tail = (ListNode *)malloc(sizeof(ListNode));
    (*head).next = body1;
    (*head).value = 1;
    (*body1).next = body2;
    (*body1).value = 2;
    (*body2).next = tail;
    (*body2).value = 3;
    (*tail).next = NULL;
    (*tail).value = 4;

    ListNode **phead = &head;
    PrintList(phead);
    converse(phead);
    PrintList(phead);
    getchar();
}

结构体做链表的时候是要申请内存的。

*pi = i;和pi = &i;的理解

二级指针还是得再理解理解。

这块为啥用二级指针呢,因为这个函数不是靠返回值的,操作完之后,链表的头是之前的尾巴,如果我们只是将链表的头传进来,注意链表的头指向的地址是结构体的地址,如果我们粗暴地让它指向尾巴,那么这个结构体就丢了,当然可以通过一系列交换操作,但是毫无疑问会很麻烦。用二级指针的话,这个二级指针是一个链表以外的东西,链表无论怎么动,这个东西指向谁都可以再去确定。也就是在我们操作完之后再叫二级指针指向尾巴就好了。

【第二个】

将字符串里面的所有空格换成逗号,多个换成一个。

#include "stdafx.h"
#include<iostream>
using namespace std;

void DevideString(const char *pInputStr, long lInputLen, char *pOutputStr){
    int i, j;
    for(i=0; pInputStr[i]==' '; i++);
    for(j=0; i<lInputLen; i++){
        if(pInputStr[i]!=' '){
            pOutputStr[j] = pInputStr[i];
            j++;
        }else if(pInputStr[i+1]!=' '){
            pOutputStr[j] = ',';
            j++;
        }else{
            ;
        }
    }
    pOutputStr[j] = ',';
    pOutputStr[j+1] = '\0';
}

void main(){
    while(1){
        char *strIn = (char *)malloc(sizeof(char)*1024);
        char *strOut = (char *)malloc(sizeof(char)*1024);
        scanf_s("%[^\n]", strIn,1024);
        //cout<<strlen(strIn);
        DevideString(strIn, strlen(strIn), strOut);
        cout<<strOut<<endl;
        getchar();
    }
}

scanf_s与scanf的区别是后面要加一个确定读取长度的参数。还有这个函数会吃掉空格,利用正则表达式来简单解决一下,如代码所示。

字符串的结束标志是'\0'(大概

【第三个】

字符串的去重并排序

#include "stdafx.h"
#include<iostream>
using namespace std;

void sort(char* s, int len){
    int dup = 0;
    for(int i=0; i<len-1; i++){
        for(int j=i+1; j<len;j++){
            if(s[i]!='z'+1 && s[i]==s[j]){
                s[j] = 'z'+1;
                dup++;
            }
        }
    }
    for(int i=0; i<len-1; i++){
        for(int j=0; j<len-1;j++){
            if(s[j]>s[j+1]){
               char temp = s[j];
                s[j] = s[j+1];
                s[j+1] = temp;
            }
        }
    }
    len-=dup;
    s[len] = '\0';
    cout<<s<<endl;
}
void main(){
    char s[1024];
    while(1){
        cin>>s;
        int len = strlen(s);
        sort(s,len);
    }
}

明明做的时候总有麻烦,回头一看又感觉没啥难的= =

【第四个】

给你1 2 3 4 5 6 7 8 9中间放+-或者不放,给定结果输出得到这个结果的式子有多少个

#include"stdafx.h"
#include<iostream>
using namespace std;

int cou = 0;
int all = 0;
int result;
char ops[] = {'1',' ','2',' ','3',' ','4',' ','5',' ','6',' ','7',' ','8',' ','9','='};
void mydfs(int layer, char lastop, int lastSum, int currentSum){
    if(layer!=1)
        ops[layer*2-3] = lastop;

    int currentNum = 0;
    if(lastop == '+'){
        currentNum = layer;
    }
    if(lastop == '-'){
        currentNum = -1*layer;
    }
    if(lastop == ' '){
        if(lastSum>0)
            currentNum = lastSum*10+layer;
        if(lastSum<0)
            currentNum = lastSum*10-layer;
    }
    if(layer==9){
        cou++;
        //cout<<layer<<"|"<<cou<<"\n";
        if(currentSum+currentNum == result){
            all++;
            cout<<ops<<result<<endl;
        }
        return;
    }
    mydfs(layer+1, '+', 0, currentSum+currentNum);
    mydfs(layer+1, '-', 0, currentSum+currentNum);
    mydfs(layer+1, ' ', currentNum, currentSum);
}

void main(){
    while(1){
        all = 0;
        cin>>result;
        mydfs(1, '+', 0, 0);
        cout<<all<<endl;
        getchar();
    }
}

去年大约这个时候我也做过这个题,一塌糊涂做不出来,虽然这个也有参考别人的代码,但是还是有自己的理解的。

其实就是遍历了所有的结果,之前的想法是将可能的符号做成类似表格的东西,但是结果就是很困难,一个是组合的时候你得考虑这个对应的符号是什么,另一个你得考虑字符串转数字。

这个是利用了递归,就是每一种可能的情况都去验证接下来的三种可能,在达到结束条件的时候结束,类似的问题都可以考虑这种解决方案。

递归要涉及一个“边界”问题,就是开头和结束的地方该怎么处理,像我这个程序里面,就是为1的时候怎么怎么办,然后为9的时候又做了些什么,其他的时候函数的操作应该都是完全一样的。

突然想起来以前写过一个扫雷,大约是大二的时候,console的,很简陋,代码所在的硬盘已经死了。

那个代码里面用了递归,但是效率很低很低,虽然运行时没有问题的。有空可以作死一下。

posted @ 2017-06-20 21:53  I加加  阅读(486)  评论(0编辑  收藏  举报