(C/C++) 算法,编程题

时间:2022-09-23 18:35:20

注: 如下的题目皆来自互联网,答案是结合了自己的习惯稍作了修改。

1. 求一个数的二进制中的1的个数。

int func(int x)
{
int count = ; while (x)
{
count++;
x = x& (x - );
} return count;
}

2. 已知strcpy的函数原型:char *strcpy(char *strDest, const char *strSrc)其中strDest 是目的字符串,strSrc 是源字符串。不调用C++/C 的字符串库函数,请编写函数 strcpy。

int _tmain(int argc, _TCHAR* argv[])
{
const char *srcStr = "This is a source string."; //char *desStr = (char *)malloc(sizeof(srcStr)); // Or below:
char *desStr = (char *)malloc(sizeof(char)* strlen(srcStr) + ); myStrcpy(desStr, srcStr); printf("Copy result: %s", desStr);
} char *myStrcpy(char *strDest, const char *strSrc)
{
if (strSrc == NULL || strDest == NULL)
{
return NULL;
} if (strDest == strSrc)
{
return strDest;
} char *strDestStart = strDest; while (*strDest !='\0')
{
*strDest++ = *strSrc++;
} return strDestStart;
}

3. 链表题:

一个链表的结点结构

struct Node
{
  int data ;
  Node *next ;
};
typedef struct Node Node ;

  

(1)已知链表的头结点head,写一个函数把这个链表逆序

思路: 用三个指针p0,p1,p2,从头到尾依次遍历并反转结点

int _tmain(int argc, _TCHAR* argv[])
{
int linkedListLength = 5;
Node *myList = new Node();
Node *p = myList;
printf("Original linked list is:");
for (int i = 0; i < linkedListLength; i++)
{
Node *node = new Node();
node->data = i;
printf(" %d", i);
p->next = node;
p = node;
} Node *reversedMyList = ReverseLinkedList(myList); printf("\r\nReversed linked list is:");
Node *r = reversedMyList;
while (r->next != NULL)
{
printf(" %d", r->data);
r = r->next;
}
} Node *ReverseLinkedList(Node *head)
{
// NULL
if (head == NULL)
{
return NULL;
} // One node only.
if (head->next == NULL)
{
return head;
} // Two or more than two nodes.
Node *p0 = head;
Node *p1 = p0->next;
Node *p2 = p1->next; //p2 maybe null; p0->next = NULL; while (p2 != NULL)
{
p1->next = p0;
p0 = p1;
p1 = p2;
p2 = p2->next;
} p1->next = p0;
return p1;
}

(2)已知两个链表head1 和head2 各自有序,请把它们合并成一个链表依然有序。(保留所有结点,即便大小相同)

思路: 从head1 和 head2 中找一个较小值定义为head,然后一次用p0,p1遍历两个链表,逐步的插入到新链表里(currnt)。

int _tmain(int argc, _TCHAR* argv[])
{
Node *p0 = new Node();
Node *p1 = new Node();
int data0[5] = { 1, 3, 5, 8, 10};
int data1[3] = { 2, 6, 7 }; Node *head0 = p0;
Node *head1 = p1;
for (int i = 0; i < sizeof(data0)/sizeof(data0[0]); i++)
{
Node *tmp0 = new Node();
tmp0->data = data0[i];
p0->next = tmp0;
p0 = p0->next;
} for (int j = 0; j < sizeof(data1)/sizeof(data1[0]); j++)
{
Node *tmp1 = new Node();
tmp1->data = data1[j];
p1->next = tmp1;
p1 = p1->next;
} head0 = head0->next;
head1 = head1->next;
Node *mergedList = MergeSortedLinkedList(head0, head1);
} Node *MergeSortedLinkedList(Node *head0, Node *head1)
{
if (head0 == NULL)
{
return head1;
} if (head1 == NULL)
{
return head0;
} // Set new head for new merged sorted list.
Node *head = NULL;
Node *p0 = head0;
Node *p1 = head1;
if (head0->data < head1->data)
{
head = head0;
p0 = p0->next;
}
else
{
head = head1;
p1 = p1->next;
} Node *current = head;
while (p0 != NULL && p1 != NULL)
{
// Insert the value which is smaller.
if (p0->data < p1->data)
{
current->next = p0;
current = p0;
p0 = p0->next;
}
else
{
current->next = p1;
current = p1;
p1 = p1->next;
} } // All of nodes of one list have been added into new merged list. so add the rest nodes of the other list.
if (p0 == NULL)
{
current->next = p1;
} if (p1 == NULL)
{
current->next = p0;
} return head;
}

另外可以也可以采用递归(recursive)算法:

顺便补充一下递归算法的特点,其关键就是定义一个递归公式和递归结束条件。

(1) 递归就是在过程或函数里调用自身。
(2) 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
(3) 递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。所以一般不提倡用递归算法设计程序。
(4) 在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。所以一般不提倡用递归算法设计程序。
 
Node * MergeRecursive(Node *head0, Node *head1)
{
if (head0 == NULL)
{
return head1;
} if (head1 == NULL)
{
return head0;
} Node *head = NULL;
if (head0->data < head1->data)
{
head = head0;
head->next = MergeRecursive(head0->next, head1);
}
else
{
head = head1;
head->next = MergeRecursive(head0, head1->next);
} return head;
}

  (3)Implement an Algorithm to check if the link list is in Ascending order?

思路: 遍历链表,只要找到某个结点的值比下个结点的值大,那么就可以判断为false。

bool IsAscendingList(Node *head)
{
Node *p = head;
while (p->next != NULL)
{
if (p->data > p->next->data)
{
return false;
} p = p->next;
}
return true;
}

  

 4.  写一个函数找出一个整数数组中,第二大的数
思路:一次遍历数组找出最大和次大数。
int _tmain(int argc, _TCHAR* argv[])
{
int data0[5] = { 1, 3, 9, 8, 10};
//int data1[7] = { 9, 1, 2, 4, 6, 10};
int data1[7] = { 9, 4, 7, 6, 6}; int secMax0 = FindSecondMax(data0, sizeof(data0) / sizeof(data0[0]));
int secMax1 = FindSecondMax(data1, sizeof(data1) / sizeof(data1[0]));
} int FindSecondMax(int *data, int dataLength)
{
if (dataLength <= 1)
{
printf("The length of data should be more than 1.");
return -1;
} int max = data[0];
int secondMax = MIN_INT; for (int i = 1; i < dataLength; i++)
{
if (data[i] > max)
{
secondMax = max;
max = data[i];
}
else
{
if (data[i] > secondMax)
{
secondMax = data[i];
}
}
} return secondMax;
}

5. 将数a、b的值进行交换,并且不使用任何中间变量.

思路: 采用异或运算(三次异或后,就被交换), 或加减运算。

int _tmain(int argc, _TCHAR* argv[])
{
int a = 18;
int b = 32; // Swap withouth other variables. 3 times XOR will swap two values. (1^1 = 0, 0^0 =0, 1^0 =1, 0^1 =1).
a ^= b;
b ^= a;
a ^= b; printf("a:%d, b:%d", a, b); // method2
a = a + b;
b = a - b;
a = a - b; printf("a:%d, b:%d", a, b); }

6. 题目:在一个字符串中找到第一个只出现一次的字符。如输入abaccdeff,则输出b。

分析:这道题是2006 年google 的一道笔试题。

思路:采用bitmap或者byteArray的思路,遍历字符串,每个字符对应的整数值为index。 Array里保存字符出现的次数。

// Assuming the char is ASCII
char FirstSingleChar(char *str)
{
int bitmap[255];
memset(bitmap, 0, 255 * sizeof(int)); char *p = str; while (*p != '\0')
{
bitmap[*p]++;
p++;
} p = str;
while (*p!='\0')
{
if (bitmap[*p] == 1)
{
return *p;
}
} return '\0';
}

7.题目:输入一个表示整数的字符串,把该字符串转换成整数并输出。
例如输入字符串"345",则输出整数345。

思路: 遍历字符串,逐字符转换为整数(和‘0'做差), 其中注意一下对负数和数字的判断。

int ConvertStrToInt(char *str)
{
char *p = str;
int result = 0;
int asciiToInt = 0;
bool isPostive = true; if (*p == '-')
{
isPostive = false;
p++;
}
else if (*p == '+')
{
p++;
} while (*p != '\0')
{
if (IsNumber(*p))
{
asciiToInt = *p - '0';
result = result * 10 + asciiToInt;
p++;
}
else
{
//Had better throw exception here.
printf("Illegal number: %c", *p);
break;
}
} if (!isPostive)
{
result = 0 - result;
} return result;
}

8.  Reverse a string.

思路: 用两个指针指向一头一尾。然后向中间遍历,并逐个字符交换。

int _tmain(int argc, _TCHAR* argv[])
{
// char *strForTest = "+345abc" will cause "access violation writing location". http://*.com/questions/14664510/access-violation-writing-location
char strForTest[] = "I like money";
ReverseWordsInSentence(strForTest);
} void ReverseString(char *str)
{
int strLength = strlen(str);
ReverseStringInFixedLength(str, strLength);
} void ReverseStringInFixedLength(char *str, int strLength)
{
char *p1 = str;
char *p2 = str + strLength -1;
char tmp;
while (p1 < p2)
{
// Swap two chars.
tmp = *p1;
*p1 = *p2;
*p2 = tmp; p1++;
p2--;
}
}

  

9. Revese words in a sentense. for example. reverse "I like money" to "money like I".

思路:Reverse the whole string, then reverse each word. Using the reverseStringInFixedLength() above.

void ReverseWordsInSentence(char *sen)
{
ReverseString(sen); char *pStartOfWord = sen;
char *p = pStartOfWord; while (*p != '\0')
{
// Skip blank spaces.
while (*p == ' ' && *p != '\0')
{
p++;
} pStartOfWord = p; while (*p != ' ' && *p != '\0')
{
p++;
} int wordLength = p - pStartOfWord; ReverseStringInFixedLength(pStartOfWord, wordLength);
}
}

10.  给出一个数组,还有一个给定的数,打印出数组中的一对数(不重复),使其和等于指定的数

思路:先排序(快排),然后再用两个指针从头尾依次向中间遍历。如果和大于期待的值,那么左移right指针,如果小于期待的值,那么右移left指针。

For sorted array,  the time complexity is O(n).
For unsorted array, we may do a quick sort and then call our method. The time complexity is O(nlogn). Here is the C++ sample codes, and I have checked it works well. int _tmain(int argc, _TCHAR* argv[])
{
int nums[7] = { 1, 2, 3, 3, 4, 4, 5 }; printUniquePairs(nums, 7, 7); } void printUniquePairs(int *numbers, int numbersLength, int expectedSum)
{
int sum = 0; //Augrments judgements. e.g. Null, length.
if (numbersLength < 2)
{
printf("Number length should be more than 2.");
return;
} // Quick sort.
QuickSort(numbers); // Use two points (left, and right) moving from two sides into the center.
int *p1 = numbers;
int *p2 = numbers + numbersLength - 1;
int previousP1Value;
int previousP2Value; while (p1 < p2)
{
sum = *p1 + *p2;
previousP1Value = *p1;
previousP2Value = *p2; if (sum == expectedSum)
{
printf("Print unique pair: %d, %d.", *p1, *p2); p1++;
p2--; // If the value is duplicated, then skip.
if (previousP1Value == *p1)
{
p1++;
} if (previousP2Value == *p2)
{
p2--;
} }
else if (sum < expectedSum)
{
p1++; // If the value is duplicated, then skip.
if (previousP1Value == *p1)
{
p1++;
}
}
else if (sum > expectedSum)
{
p2--; if (previousP2Value == *p2)
{
p2--;
}
}
}

  

(C/C++) 算法,编程题的更多相关文章

  1. C算法编程题系列

    我的编程开始(C) C算法编程题(一)扑克牌发牌 C算法编程题(二)正螺旋 C算法编程题(三)画表格 C算法编程题(四)上三角 C算法编程题(五)“E”的变换 C算法编程题(六)串的处理 C算法编程题 ...

  2. C算法编程题(七)购物

    前言 上一篇<C算法编程题(六)串的处理> 有些朋友看过我写的这个算法编程题系列,都说你写的不是什么算法,也不是什么C++,大家也给我提出用一些C++特性去实现问题更方便些,在这里谢谢大家 ...

  3. C算法编程题(六)串的处理

    前言 上一篇<C算法编程题(五)“E”的变换> 连续写了几篇有关图形输出的编程题,今天说下有关字符串的处理. 程序描述 在实际的开发工作中,对字符串的处理是最常见的编程任务.本题目即是要求 ...

  4. C算法编程题(五)&OpenCurlyDoubleQuote;E”的变换

    前言 上一篇<C算法编程题(四)上三角> 插几句话,说说最近自己的状态,人家都说程序员经常失眠什么的,但是这几个月来,我从没有失眠过,当然是过了分手那段时期.每天的工作很忙,一个任务接一个 ...

  5. C算法编程题(四)上三角

    前言 上一篇<C算法编程题(三)画表格> 上几篇说的都是根据要求输出一些字符.图案等,今天就再说一个“上三角”,有点类似于第二篇说的正螺旋,输出的字符少了,但是逻辑稍微复杂了点. 程序描述 ...

  6. C算法编程题(三)画表格

    前言 上一篇<C算法编程题(二)正螺旋> 写东西前还是喜欢吐槽点东西,要不然写的真还没意思,一直的想法是在博客园把自己上学和工作时候整理的东西写出来和大家分享,就像前面写的<T-Sq ...

  7. C算法编程题(二)正螺旋

    前言 上一篇<C算法编程题(一)扑克牌发牌> 写东西前总是喜欢吐槽一些东西,还是多啰嗦几句吧,早上看了一篇博文<谈谈外企涨工资那些事>,里面楼主讲到外企公司包含的五类人,其实不 ...

  8. C算法编程题(一)扑克牌发牌

    前言 上周写<我的编程开始(C)>这篇文章的时候,说过有时间的话会写些算法编程的题目,可能是这两天周末过的太舒适了,忘记写了.下班了,还没回去,闲来无事就写下吧. 因为写C++的编程题和其 ...

  9. 面试题&lpar;C&num;算法编程题&rpar;

    1>用C#写一段选择排序算法,要求用自己的编程风格.答:private int min;    public void xuanZhe(int[] list)//选择排序    {        ...

  10. 需掌握 - JAVA算法编程题50题及答案

    [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? //这是一个菲波拉契数列问题publi ...

随机推荐

  1. 走进异步编程的世界 - 开始接触 async&sol;await

    [C#] 走进异步编程的世界 - 开始接触 async/await   走进异步编程的世界 - 开始接触 async/await 序 这是学习异步编程的入门篇. 涉及 C# 5.0 引入的 async ...

  2. JavaScript和DOM的产生与发展

    首先本篇文章摘自:http://itbilu.com/javascript/js/Vyxodm_1g.html 非常感谢本篇文章的作者,他理清了我映像中混乱的DOM Level级别.让我知道了DOM0 ...

  3. 合理计划 dictionary cache 大小

    [数据字典缓冲区(Data Dictionary Cache)  ] 用于存放Oracle系统管理自身所需要的所有信息,包括登录的用户名.用户对象.权限等. 查看 data dictionary ca ...

  4. C&plus;&plus;中printf和scanf的用法

    (一)printf的用法 printf:按格式打印,向控制台输出.print:打印 ,f:formate,格式化. 在使用printf向控制台输出时,不建议使用中文字符串,中文字符串的问题比较复杂,有 ...

  5. python dom操作

    1.DOM介绍 (1)什么是DOM DOM:文档对象模型.DOM 为文档提供了结构化表示,并定义了如何通过脚本来访问文档结构.目的其实就是为了能让js操作html元素而制定的一个规范. DOM就是由节 ...

  6. sublime3 前端个人常用插件及快捷键

    首先先介绍如何启用插件安装功能: 打开Sublime 3,然后按 ctrl+` 或者在View → Show Console 在打开的窗口里黏贴这个网站上的代码(注意: Sublime 2和3所黏贴的 ...

  7. Hadoop基本介绍

    1.Hadoop的整体框架 Hadoop由HDFS.MapReduce.HBase.Hive和ZooKeeper等成员组成,其中最基础最重要元素为底层用于存储集群中所有存储节点文件的文件系统HDFS( ...

  8. 『科学计算』L0、L1与L2范数&lowbar;理解

     『教程』L0.L1与L2范数 一.L0范数.L1范数.参数稀疏 L0范数是指向量中非0的元素的个数.如果我们用L0范数来规则化一个参数矩阵W的话,就是希望W的大部分元素都是0,换句话说,让参数W是稀 ...

  9. 《Java从入门到放弃》JavaSE入门篇:变量

    变量是什么玩意呢? 变量,顾名思义就是能变化的量 - - 好吧,举个栗子. 图片上的各种餐具,就是变量,因为同一个盘子可以在不同的时间装不同的菜,在这一桌可以装土豆肉丝,在下一桌可以装清炒黄瓜(当然, ...

  10. 转:使用python的Flask实现一个RESTful API服务器端

    提示:可以学习一下flask框架中对于密码进行校验的部分.封装了太多操作. 最近这些年,REST已经成为web services和APIs的标准架构,很多APP的架构基本上是使用RESTful的形式了 ...