Practice in program

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;
}



版权声明:本文为博主原创文章,未经博主允许不得转载。

posted @ 2015-05-18 17:35  J.Way.C  阅读(146)  评论(0编辑  收藏  举报