二级指针的应用-有关链表的一些小题

2014年知名互联网公司笔试题

1. 华为:

通过键盘输入一串小写字母(a~z)组成的字符串。请编写一个字符串压缩程序,将字符串中连续出席的重复字母进行压缩,并输出压缩后的字符串。
压缩规则:
    1、仅压缩连续重复出现的字符。比如字符串"abcbc"由于无连续重复字符,压缩后的字符串还是"abcbc"。
    2、压缩字段的格式为"字符重复的次数+字符"。例如:字符串"xxxyyyyyyz"压缩后就成为"3x6yz"。
要求实现函数: 
     void stringZip(const char *pInputStr, long lInputLen, char *pOutputStr);
    输入pInputStr:  输入字符串lInputLen:  输入字符串长度
    输出 pOutputStr: 输出字符串,空间已经开辟好,与输入字符串等长;
注意:只需要完成该函数功能算法,中间不需要有任何IO的输入输出
示例 
    输入:“cccddecc”   输出:“3c2de2c”
    输入:“adef”     输出:“adef”
    输入:“pppppppp” 输出:“8p”

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

/*
 * HuaWei: A string compressed example
 * */
void stringZip(const char *pInputStr, char *pOutputStr) {
    int len = strlen(pInputStr);
    char *tmp = (char *)malloc(sizeof(len * sizeof(char)));
    int start = 0;
    int end = start + 1;
    int cnt = 0;
    int i = 0;

    while(pInputStr[start]) {
	if(pInputStr[start] == pInputStr[end]) {
	    cnt++;
	    end++;
	}
	else {
	    if(cnt == 0)  tmp[i++] = pInputStr[start];
	    else if(cnt > 0) {
		tmp[i++] = cnt + 1 + '0';
		tmp[i++] = pInputStr[start];
		cnt = 0;
	    }
	    start = end;
	    end = start + 1;
	}
    }
    tmp[i] = '\0';
    strncpy(pOutputStr, tmp, strlen(tmp));
    free(tmp);
}
void main() {  
    char str[1024];  
    char compress_str[1024];
    printf("Input a string:");
    gets(str);  
    stringZip(str, compress_str);
    printf("The compressed string is:");
    puts(compress_str);
}  


2. 迅雷:

已知集合A和B的元素分别用不含头结点的单链表存储,函数difference()用于求解集合A与B的差集,并将结果保存在集合A的单链表中。例如,若集合A={5,10,20,15,25,30},集合B={5,15,35,25},完成计算后A={10,20,30}。

#include <stdio.h>
#include <stdlib.h>
/*
 * XunLei: difference of linked list
 * */
typedef struct node {
    int elem;
    struct node *next;
}node;

void create(node **head, int n) {
    int elem;
    int i;
    node *p;
    node *r;
    for(i = 0;i < n;i++) {
	if(scanf("%d", &elem) != 1) {
	    perror("input error!\n");
	    exit(1);
	}
	p = (node *)malloc(sizeof(node *));
	if(!p) {
	    perror("memory error!\n");
	    exit(2);
	}
	p->elem = elem;
	p->next = 0;
	if(!*head) *head = p;
	else {
	    r->next = p;
	}
	r = p;
    }
}
void show(node *head) {
    node *p = head;
    while(p) {
	printf("%d\n", p->elem);
	p = p->next;
    }
}
void difference(node **LA, node *LB) {
    node *p, *q, *pre;
    node *head;
    p = *LA;
    pre = *LA;
    head = p;
    while(p) {
	q = LB;
	while(q) {
	    if(p->elem == q->elem) break;
	    q = q->next;
	}
	if(q) {
	    if(pre == p) {
		p = p->next;
		pre->next = 0;
		free(pre);
		pre = p;
		head = p;
	    }
	    else {
		pre->next = p->next;
		p->next = 0;
		free(p);
		p = pre->next;
	    }
	}
	else {
	    pre = p;
	    p = p->next;
	}
    }
    *LA = head;
}
void main() {
    node *head1 = NULL, *head2 = NULL;
    create(&head1, 5);
    printf("----------\n");
    create(&head2, 3);
    difference(&head1, head2);
    printf("----------\n");
    show(head1);
}

二级指针的应用-有关链表的一些小题_第1张图片

3.美团网:

1、链表翻转。给出一个链表和一个数k,比如链表1→2→3→4→5→6,k=2,则翻转后2→1→4→3→6→5,若k=3,翻转后3→2→1→6→5→4,若k=4,翻转后4→3→2→1→5→6,用程序实现:

#include <stdio.h>
#include <stdlib.h>
/*
 * XunLei: difference of linked list
 * */
typedef struct node {
    int elem;
    struct node *next;
}node;

void create(node **head, int n) {
    int elem;
    int i;
    node *p;
    node *r;
    for(i = 0;i < n;i++) {
	if(scanf("%d", &elem) != 1) {
	    perror("input error!\n");
	    exit(1);
	}
	p = (node *)malloc(sizeof(node *));
	if(!p) {
	    perror("memory error!\n");
	    exit(2);
	}
	p->elem = elem;
	p->next = 0;
	if(!*head) *head = p;
	else {
	    r->next = p;
	}
	r = p;
    }
}
void show(node *head) {
    node *p = head;
    while(p) {
	printf("%d\n", p->elem);
	p = p->next;
    }
}
/*
 * reverse the sub link list the length of which is k
 * */
void reverse_node(node **LA, int k) {
    node *head;       // the temporary head node 
    node *start;      // the start node of every sub link list   
    node *end;        // the end node of every  sub link list 
    node *p;          // the current node of orignal link list 
    node *r;          // the removed node 

    head = (node *)malloc(sizeof(node *));
    if(!head) {
	perror("memory error!\n");
	exit(1);
    }
    head->next = NULL;
    start = head;
    int cnt = 0;
    p = *LA;

    while(p) {
	if(cnt < k) {
	    r = p;
	    p = p->next;
	    r->next = start->next;
	    start->next = r;
	    if(cnt == 0) end = r;
	    cnt++;
	}
	else if(cnt == k) {
	    cnt = 0;
	    start = end;
	}
	else break;
    }
    *LA = head->next;
    head->next = NULL;
    free(head);
}
void main() {
    node *head = NULL;
    create(&head, 6);
    printf("----------\n");
    int k;
    printf("k = ");
    if(scanf("%d", &k) == 1 && k > 0) reverse_node(&head, k);
    show(head);
}

二级指针的应用-有关链表的一些小题_第2张图片

你可能感兴趣的:(二级指针的应用-有关链表的一些小题)