(C/C++) 算法,编程题
注: 如下的题目皆来自互联网,答案是结合了自己的习惯稍作了修改。
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)算法:
顺便补充一下递归算法的特点,其关键就是定义一个递归公式和递归结束条件。
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;
}
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://stackoverflow.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++) 算法,编程题的更多相关文章
- C算法编程题系列
我的编程开始(C) C算法编程题(一)扑克牌发牌 C算法编程题(二)正螺旋 C算法编程题(三)画表格 C算法编程题(四)上三角 C算法编程题(五)“E”的变换 C算法编程题(六)串的处理 C算法编程题 ...
- C算法编程题(七)购物
前言 上一篇<C算法编程题(六)串的处理> 有些朋友看过我写的这个算法编程题系列,都说你写的不是什么算法,也不是什么C++,大家也给我提出用一些C++特性去实现问题更方便些,在这里谢谢大家 ...
- C算法编程题(六)串的处理
前言 上一篇<C算法编程题(五)“E”的变换> 连续写了几篇有关图形输出的编程题,今天说下有关字符串的处理. 程序描述 在实际的开发工作中,对字符串的处理是最常见的编程任务.本题目即是要求 ...
- C算法编程题(五)“E”的变换
前言 上一篇<C算法编程题(四)上三角> 插几句话,说说最近自己的状态,人家都说程序员经常失眠什么的,但是这几个月来,我从没有失眠过,当然是过了分手那段时期.每天的工作很忙,一个任务接一个 ...
- C算法编程题(四)上三角
前言 上一篇<C算法编程题(三)画表格> 上几篇说的都是根据要求输出一些字符.图案等,今天就再说一个“上三角”,有点类似于第二篇说的正螺旋,输出的字符少了,但是逻辑稍微复杂了点. 程序描述 ...
- C算法编程题(三)画表格
前言 上一篇<C算法编程题(二)正螺旋> 写东西前还是喜欢吐槽点东西,要不然写的真还没意思,一直的想法是在博客园把自己上学和工作时候整理的东西写出来和大家分享,就像前面写的<T-Sq ...
- C算法编程题(二)正螺旋
前言 上一篇<C算法编程题(一)扑克牌发牌> 写东西前总是喜欢吐槽一些东西,还是多啰嗦几句吧,早上看了一篇博文<谈谈外企涨工资那些事>,里面楼主讲到外企公司包含的五类人,其实不 ...
- C算法编程题(一)扑克牌发牌
前言 上周写<我的编程开始(C)>这篇文章的时候,说过有时间的话会写些算法编程的题目,可能是这两天周末过的太舒适了,忘记写了.下班了,还没回去,闲来无事就写下吧. 因为写C++的编程题和其 ...
- 面试题(C#算法编程题)
1>用C#写一段选择排序算法,要求用自己的编程风格.答:private int min; public void xuanZhe(int[] list)//选择排序 { ...
- 需掌握 - JAVA算法编程题50题及答案
[程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? //这是一个菲波拉契数列问题publi ...
随机推荐
- tomcat直接访问
解决了:http://blog.csdn.net/zhangyulin54321/article/details/8876320 <Context path="" docBa ...
- SQL注入测试平台 SQLol -2.SELECT注入测试
前面,我们已经安装好了SQLol,打开http://localhost/sql/,首先跳转到http://localhost/sql/select.php,我们先从select模块进行测试. 一条完成 ...
- magic矩阵 分类: 数学 2015-07-31 22:56 2人阅读 评论(0) 收藏
魔方矩阵 魔方矩阵是有相同的行数和列数,并在每行每列.对角线上的和都相等.你能构造任何大小(除了2x2)的魔方矩阵. 1.历史 魔方又称幻方.纵横图.九宫图,最早记录于我国古代的洛书.据说 ...
- JavaScript个人学习记录总结(二)——验证表单输入之模式匹配
该示例检查从文本窗口部件中获取姓名和电话号码这两个表单数据的有效性.当文本框中的值发生变化时,即引发一个change事件,从而可以调用一个函数来检查这两个输入值的格式是否正确. validator.h ...
- scala言语基础学习三
map的操作 访问fangwemap元素 修改map元素 遍历map sortmap和linkmap map元素类型tuple
- svn 安装 、使用(1)
写在开头: 虽然网络极大的方便了我们查找答案,而且有很多人写各样的博客.但每个人在实际中的情况不一样,遇到的问题也不一样,大牛们会把步骤写的很简单,可能真的是怕麻烦,但显然就有一些东西已经不适合一部分 ...
- thinkphp 验证码的使用
在thinkphp中使用验证码很容易,只要调用thinkphp现有的方法就可以.当然,php的GD库肯定是要开的(就是在php.ini中要加载gd模块). thinkphp 3.2 --------- ...
- Introduction to Monte Carlo Tree Search (蒙特卡罗搜索树简介)
Introduction to Monte Carlo Tree Search (蒙特卡罗搜索树简介) 部分翻译自“Monte Carlo Tree Search and Its Applicati ...
- Oracle 10g bigfile表空间、smallfile 表空间
smallfile tablespace设置不同大小的db_block_size时数据文件允许的最大大小 db_block_size=2KB,2KB*4M=8192M 8Gdb_block_ ...
- Linux中的15个‘echo’ 命令实例
echo是一种最常用的与广泛使用的内置于Linux的bash和C shell的命令,通常用在脚本语言和批处理文件中来在标准输出或者文件中显示一行文本或者字符串. echo命令的语法是: echo [选 ...