字符串处理三题之三

【更新】

2012-10-02,【问题3】添加新的编程实现方法。

【问题1】

判断一个数是否为回文数?

例如:123321是回文数,123421不是回文数。

【实现代码】

int isHuiwen(int num)
{
	char *str = (char *)malloc(100);
	
	int isHuiwen = 1;

	char *start = itoa(num, str, 10);
	char *end = itoa(num, str, 10) + strlen(str) - 1;

	for(; end > start;)
	{
		if(*end != *start)
		{
			isHuiwen = 0;
			break;
		}

		start++;
		end--;
	}

	return isHuiwen;
}


【测试代码】

printf("%d\n", isHuiwen(123221));
printf("%d\n", isHuiwen(1223221));


【问题2】

删除字符串中多余的空格,如果字符中的空格大于1就删除多余的空格,仅保留一个空格。

【实现代码】

static int is_white(char ch)
{
	return ch ==' '||ch=='\t' || ch == '\v' || ch =='\f'|| ch =='\n'|| ch =='\r';
}

void deblank(char *in, char *out)
{
	for(; *in != '\0';)
	{
		if(is_white(*in))
		{
			*out++ = *in++;
			while(is_white(*in)){in++;}
		}
		else
		{
			*out++ = *in++;
		}
	}

	*out = '\0';
}


【测试代码】

char *in = "Hello      world  !   Test   for    deblank!";
char *out = (char *)malloc((strlen(in)+1)*sizeof(char));

deblank(in, out);
printf("%s\n",in);
printf("%s\n",out);
free(out);
out = NULL;

 

【问题3】

单链表逆序。

例如:原单链表为head->1->2->3,逆序后为3->2->1->head。

【实现代码】

void converse(ListNode **head)
{ 
	ListNode* p1 = *head;   
	ListNode* p2 = p1->next;
	
	(*head)->next = NULL;   
    	while (p2)   
    	{   
		p1 = p2;   
		p2 = p2->next;   
		p1->next = *head;   
		*head = p1;   //调整头结点
	}   
}

 

【测试代码】

ListNode *head = malloc(sizeof(ListNode));
ListNode *node1 = malloc(sizeof(ListNode));
ListNode *node2 = malloc(sizeof(ListNode));
ListNode *node3 = malloc(sizeof(ListNode));
ListNode *node4 = malloc(sizeof(ListNode));
ListNode *node;
		
head->value = 1;
node1->value = 2;
node2->value = 3;
node3->value = 4;
node4->value = 5;
head->next = node1;
node1->next = node2;
node2->next =node3;
node3->next = node4;
node4->next = NULL;
	
for(node = head; node !=0; node = node->next)
{
	printf("%d ", node->value);
}
printf("\n");
	
converse(&head);
	
for(node = head; node !=NULL; node = node->next)
{
	printf("%d ", node->value);
}
printf("\n");

 

【分析】

下面,以head->1->2->3->NULL为例,对单链表逆序进行分析。

原链表如图1所示:

图1

逆序后的链表如图2所示:

图2

图3

【步骤】

1 定义临时结点,保存原链表

ListNode* p1 = *head;   

 

2 定义迭代结点
ListNode* p2 = p1->next;

 

3 断开head 和 1->2->3->NULL,让head指向NULL

图4

图5

(*head)->next = NULL;


4 若迭代结点(开始的时候为head->next,即指向1号结点)不为空,则说明结点至少有2个,则进行逆序,否则什么也不做。

while(p2)
{

}

5 让p1指向p2,即指向迭代结点,此时为结点1

p1 = p2; 


6 让迭代结点进行迭代

p2 = p2->next;

 

7 断开1号结点和2号结点

图6

 

8 让1号结点指向head

p1->next = *head; 


9 调整头结点为1号结点

*head = p1;

图7

 

10 迭代p2后,p2 = p2->next(上一轮循环),即指向2号结点。使 p1指向p2(p1 = p2),即指向2号结点。然后,让2号结点指向1号结点(p1->next = *head,即当前头结点),断开2号结点和3号结点。调整2号结点为头结点(*head = p1)。

p1 = p2;   
p2 = p2->next;   
p1->next = *head;   
*head = p1; 

 

图8

图9

 

11 重复上述步骤, 迭代p2后,p2 = p2->next(上一轮循环),即指向3号结点。使p1指向p2(p1 = p2),即指向3号结点。让3号结点指向2号结点(p1->next = *head,即当前头结点)。调整3号结点为头结点(*head = p1)。

p1 = p2;   
p2 = p2->next;   
p1->next = *head;   
*head = p1; 

 

图10

 

12 迭代p2,p2 = p2->next。此时,p2为NULL,结束循环。

 

方法2(2012-10-02)

思路一样,编程方法不同

void converse(ListNode **head)
{ 
	ListNode *previous;
	ListNode *next;

	for(previous = NULL; *head != NULL; *head = next)
	{
		next = (*head)->next;
		(*head)->next = previous;
		previous = (*head);
	}

	*head = previous;
}


方法3  递归法实现

Node* RecReverseList(Node* head) //递归方法  
{     
    if (!head || !head->next)  
    {  
        return head;  
    }  
    Node *newhead = RecReverseList(head->next);  
    head->next->next = head;  
    head->next = NULL;  
    return newhead;  
}   


 

 

 

转载请标明出处,仅供学习交流,勿用于商业目的

Copyright @ http://blog.youkuaiyun.com/tandesir


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值