题目:实现一个函数,将两个字符串连接起来。
输入:字符串1:abc;字符串2:defg
输出:abcdefg
优化目标:无
#include <stdio.h>
#include <string.h>
#define MAXS 10
/*
*把一个字符串连接到另一个字符串位
*@*s:字符串1的首地址指针
*@*s:字符串2的首地址指针
*/
char *str_cat( char *s, char *t ){
//字符串s的长度
int len = strlen(s);
//长度越界
if(len + strlen(t) > MAXS){
return NULL;
}
//连接
for(int i=0; i<strlen(t); i++){
s[len + i] = t[i];
}
return s;
}
int main()
{
char *p;
char str1[MAXS+MAXS] = {'\0'}, str2[MAXS] = {'\0'};
scanf("%s%s", str1, str2);
p = str_cat(str1, str2);
printf("%s\n%s\n", p, str1);
return 0;
}
题目:实现一个删除字符串中的指定字符的简单函数。
输入:指定字符a;字符串:happy new year
输出:hppy new yer
优化目标:以空间换时间(见代码2)
注意事项:把字符串a赋给字符串b,用strcpy(b, a),而不是b = a。
代码1:时间复杂度O(n^2)
#include <stdio.h>
#include <string.h>
#define MAXN 20
/*
*删除特定字符函数
*@str:数组指针
*@c:待删除字符
*/
void delchar( char *str, char c ){
for(int i=0; i<strlen(str); i++){
if(c == str[i]){
for(int j=i; j<strlen(str); j++){
str[j] = str[j+1];
}
}
}
}
/*
*输入s的元素
*s:字符数组
*/
void ReadString( char s[] ){
int i = 0;
char c;
scanf("%c", &c);
while(c != '#'){//输入#表示输入结束
s[i] = c;
i++;
scanf("%c", &c);
}
}
int main()
{
char str[MAXN], c;
scanf("%c\n", &c);
ReadString(str);
delchar(str, c);
printf("%s\n", str);
return 0;
}
代码2:时间复杂度O(n)
#include <stdio.h>
#include <string.h>
#define MAXN 20
/*
*删除特定字符函数
*@str:数组指针
*@c:待删除字符
*/
void delchar( char *str, char c ){
char s[MAXN];
int j=0;
for(int i=0; i<strlen(str); i++){
if( str[i] != c){
s[j] = str[i];
j++;
}
}
//将s赋值给str
strcpy(str, s);
}
/*
*输入s的元素
*s:字符数组
*/
void ReadString( char s[] ){
int i = 0;
char c;
scanf("%c", &c);
while(c != '#'){//输入#表示输入结束
s[i] = c;
i++;
scanf("%c", &c);
}
}
int main()
{
char str[MAXN], c;
scanf("%c\n", &c);
ReadString(str);
delchar(str, c);
printf("%s\n", str);
return 0;
}
题目:求实现两个函数,分别将读入的数据存储为单链表、将链表中所有存储了某给定值的结点删除。
输入:结点:10 11 10 12 10 -1(-1表示输入结束)。删除结点:10
输出:11 12
优化目标:带头节点的链表
方法1:不带头节点的单链表。需要注意的是,如果第一个结点就是要删除的结点,则需要单独处理,因为第一个结点没有前驱结点。如果第一个结点删除后,新的第一个结点仍然是要删除的结点,则继续上面的单独处理。
#include <stdio.h>
#include <stdlib.h>
struct ListNode {
int data;
struct ListNode *next;
};
//建立链表。不带头节点
struct ListNode *readlist(){
int n;
scanf("%d", &n);
struct ListNode* head, *p, *q;
//初始化链表
while(n != -1){
p = (struct ListNode*)malloc(sizeof(struct ListNode));
p->data = n;
p->next = NULL;
if(q == NULL){//初始化第一哥结点
q = p;
head = p;//head指向第一个结点
}else{
q->next = p;
q = p;
}
scanf("%d", &n);
}
//返回第一个结点指针
return head;
}
/*
*删除链表指定值的结点。不带头结点
*@L:链表指针
*@m:待删除的值
*/
struct ListNode *deletem( struct ListNode *L, int m ){
//判断参数的合法性
if(L == NULL){
return NULL;
}
//辅助指针p
struct ListNode *p = L;
//q指向第二数据结点
struct ListNode *q = p->next;
//因为没有头节点,所以如果第一个结点就是要删除的结点,要单独操作
//第一个结点没有前驱结点
while(L->data == m){
L->next = NULL;//把第一哥结点与后面的结点断开,即删除
L = q;//q一开始指向第二个数据结点,再赋给L,则L又指向了断开第一个结点后,新链表的第一个结点
p = L;
q = q->next;//q往后移
}
//通过上面的操作,第一个结点已经不是要删除的结点了,所以从第二个结点开始判断
while(q){
if(q->data == m){
p->next = q->next;
}else{
p = q;
}
q = q->next;
}
return L;
}
/*
*打印结点
*@L:链表指针
*/
void printlist( struct ListNode *L )
{
//判断参数的合法性
if(L == NULL){
return;
}
struct ListNode *p = L;
while (p) {
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
int main()
{
int m;
struct ListNode *L = readlist();
scanf("%d", &m);
L = deletem(L, m);
printlist(L);
return 0;
}
方法2: 带头节点的单链表
注意:带头结点的链表,打印结点时应该从第一个数据结点开始,也就是从L->next开始打印。
#include <stdio.h>
#include <stdlib.h>
struct ListNode {
int data;
struct ListNode *next;
};
//建立链表。不带头节点
struct ListNode *readlist(){
int n;
//初始化头节点
struct ListNode* head = (struct ListNode*)malloc(sizeof(struct ListNode));
head->data = NULL;
head->next = NULL;
scanf("%d", &n);
//辅助指针p指向头节点
struct ListNode* p = head;
//初始化链表
while(n != -1){
struct ListNode* q = (struct ListNode*)malloc(sizeof(struct ListNode));
q->data = n;
q->next = NULL;
p->next = q;
p = q;
scanf("%d", &n);
}
//返回第一个结点指针
return head;
}
/*
*删除链表指定值的结点。不带头结点
*@L:链表指针
*@m:待删除的值
*/
struct ListNode *deletem( struct ListNode *L, int m ){
//判断参数的合法性
if(L == NULL){
return NULL;
}
//辅助指针p指向头节点
struct ListNode *p = L;
//q指向第一数据结点
struct ListNode *q = p->next;
while(q != NULL){
//如果q是要删除的结点,则p不移动,删除该结点后,q往后移;否则,都往后移
if(q->data == m){
p->next = q->next;
}else{
p = q;
}
q = q->next;
}
return L;
}
/*
*打印结点
*@L:链表指针
*/
void printlist( struct ListNode *L )
{
//判断参数的合法性
if(L == NULL){
return;
}
//辅助指针p指向第一个数据结点
struct ListNode *p = L->next;
while (p) {
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
int main()
{
int m;
struct ListNode *L = readlist();
scanf("%d", &m);
L = deletem(L, m);
printlist(L);
return 0;
}