1. 将一个十进制整数转换成任意进制(2-36)的整数:
#include <cstdio>
#include <cstdlib>
int Tentrans2any(char* out, int len, int number, int base) {
if( !out || len < 2 || base < 2 || base > 36 ) return 0;
bool neg = number < 0 ? true : false;
int index = 0;
if ( neg ) {
out[index++] = '-';
number = -number;
}
do {
int digit = number % base;
if ( digit > 9 ) {
out[index++] = digit - 10 + 'A';
} else {
out[index++] = digit + '0';
}
number /= base;
} while ( index < len && number != 0 );
// revers
int li = neg ? 1:0;
int ri = index-1;
int temp = 0;
while ( li < ri ) {
temp = out[li];
out[li] = out[ri];
out[ri] = temp;
li++;
ri--;
}
return index;
}
int main(int argc, char** argv)
{
if ( argc < 3 ) {
printf("Usage:\n%s number base\n", argv[0]);
return 1;
}
int number = strtol(argv[1], NULL, 10);
int base = strtol(argv[2], NULL, 10);
char out[128] = {0};
int ret = Tentrans2any( out, sizeof(out), number, base);
printf("Ret %d, Number %d in %d = %s\n", ret, number, base, out);
return 0;
}
2. 位移代替乘除法
a*10 = a*8 + a*2 = a<<3 + a<1;
a / 8 = a >> 3; // 除法暂时没找到非2^n次的位移方法,比如a/10。
另外,编译器在处理a * 2^n 或 a / 2^n 时会做优化的位移处理。这个Stackoverflow给出了乘法的汇编解析。
下面这个是 12/2 的汇编过程(VS2005:cl.exe 14.00.50727.42 for 80x86),也是类似的处理。sar eax,1 即是右移1位的意思。
int i = 12;
00401014 mov dword ptr [i],0Ch
i = i / 2;
0040101B mov eax,dword ptr [i]
0040101E cdq
0040101F sub eax,edx
00401021 sar eax,1
00401023 mov dword ptr [i],eax
自己另外写了个位移的乘法小程序,并没有什么卵用。
#include <cstdio>
#include <cstdlib>
#include <string.h>
int main(int argc, char** argv) {
if ( argc < 2 ) {
printf("Usage:\n%s number * number\n", argv[0]);
return 1;
}
char line[128] = {0};
for( int i=1; i<argc; ++i ) {
strncat( line, argv[i], sizeof(line)-strlen(line)-1 );
}
char *pEnd = NULL;
long int n1 = strtol( line, &pEnd, 10);
bool negitive = false;
if ( n1 < 0 ) {
n1 = -n1;
negitive = true;
}
while( pEnd && *pEnd != 0 && *pEnd != '*' )
pEnd++;
if ( *pEnd != '*' ) {
printf("Wrong args\n");
return 2;
}
long int n2 = strtol( pEnd+1, NULL, 10 );
if ( n2 < 0 ) {
n2 = -n2;
negitive = negitive ? false:true;
}
long int result = 0;
if ( n1 != 0 && n2 != 0 ) {
int bits = sizeof(result)*8;
if ( (n2&0x01) ) result += n1;
for ( int i=1; i<bits; ++i ) {
if ( (n2&(0x01<<i)) != 0 ) {
result += (n1 << i);
}
}
if ( negitive ) result = - result;
}
printf("%s = %d\n", line, result);
return 0;
}
3. 合并两个有序的链表,下面的算法思路是在一次畅游的面试过程中得知的:既然都是有序的链表,那么就可以两个链表同时遍历,通过转移next指针来完成两个链表的完全合并。
#include <cstdio>
#include <cstdlib>
#include <ctime>
struct Node{
int data;
Node* next;
};
Node* List1 = NULL;
Node* List2 = NULL;
Node* GenerateList(int count) {
if ( count < 1 ) return NULL;
static int tkey = 0x5241;
Node head;
Node* pHead = &head;
srand( time(NULL)+tkey++ );
int begin = rand() % count;
int actcount = 0;
for( int i=begin; actcount<count; ++i ) {
if ( rand()%3 == 0 ) {
Node *pn = new Node;
pn->data = i;
pn->next = NULL;
pHead->next = pn;
pHead = pn;
actcount++;
}
}
return head.next;
}
void PrintList( Node* list ) {
int count = 0;
while ( list ) {
printf( "%d ", list->data );
list = list->next;
count ++;
}
printf(":(%d)\n", count);
}
Node* MergeSeqlists(Node* list1, Node* list2){
if ( list1 == NULL ) return list2;
if ( list2 == NULL ) return list1;
// set head
Node* head = list1->data <= list2->data ? list1:list2;
while (list1 && list2 ){
if ( list1->data <= list2->data ) {
while ( list1->next && list1->next->data <= list2->data ) {
list1 = list1->next;
continue;
}
Node* temp = list1->next;
list1->next = list2;
list1 = temp;
} else {
while ( list2->next && list2->next->data <= list1->data ) {
list2 = list2->next;
continue;
}
Node* temp = list2->next;
list2->next = list1;
list2 = temp;
}
}
return head;
}
int main(int argc, char** argv) {
if ( argc < 3 ) {
printf("Usage:\n%s list1counts list2counts\n", argv[1]);
return 1;
}
int count = strtol( argv[1], NULL, 10 );
List1 = GenerateList( count );
count = strtol( argv[2], NULL, 10 );
List2 = GenerateList( count );
PrintList( List1 );
PrintList( List2 );
Node* list = MergeSeqlists( List1, List2 );
PrintList( list );
return 0;
}
另外在剑指offer上面看到了个递归的实现方式
Node* MergeSeqlists2(Node* list1, Node* list2) {
if ( list1 == NULL ) return list2;
if ( list2 == NULL ) return list1;
Node* pHead = NULL;
if ( list1->data < list2->data ) {
pHead = list1;
pHead->next = MergeSeqlists2( list1->next, list2 );
} else {
pHead = list2;
pHead->next = MergeSeqlists2( list1, list2->next );
}
return pHead;
}