code segments

单词博弈(http://hero.csdn.net/Question/Details?ExamID=163&ID=168&bsh_bid=323983132)

甲乙两个人用一个英语单词玩游戏。两个人轮流进行,每个人每次从中删掉任意一个字母,如果剩余的字母序列是严格单调递增的(按字典序a < b < c <....<z),则这个人胜利。两个人都足够聪明(即如果有赢的方案,都不会选输的方案 ),甲先开始,问他能赢么?

输入: 一连串英文小写字母,长度不超过15,保证最开始的状态不是一个严格单增的序列。

输出:1表示甲可以赢,0表示甲不能赢。

例如: 输入 bad, 则甲可以删掉b或者a,剩余的是ad或者bd,他就赢了,输出1。

又如: 输入 aaa, 则甲只能删掉1个a,乙删掉一个a,剩余1个a,乙获胜,输出0。


结果正确,效率没别人高(虽然最后时刻还加了一个缓存进去)。

为这题目专门看了好几天的博弈论算法(五子棋什么的),不过到最后发现可以如此简单的实现(也没用上那些算法)。

在群里见有人讨论时提到α分支裁剪什么的,太高深了我没投入过多精力去研究。

#include <iostream>
#include <string>
#include <map>
using namespace std;

bool is_ordered(const string& word)
{
	if (word.length() <= 1)
		return true;
	bool order = true;
	for (int i = 1; i < word.length(); i++) {
		if (word[i] > word[i-1]) {
			continue;
		} else {
			order = false;
			break;
		}
	}
	return order;
}

typedef map<string, bool>  CacheMap;
CacheMap cachemap;

//check: at this point (word), i will win absolutely (i has one or more path to win)
//once a next point is failed for competitor, return true; all next points are successful for competitor, return false
bool check_success(const string& word)
{
	//query cahce first
	CacheMap::iterator it = cachemap.find(word);
	if (it != cachemap.end()) {
		return it->second;
	}

	if (is_ordered(word)) {
		cachemap[word] = false;
		return false;
	}
	for (int i = 0; i < word.length(); i++) {
		string nextword(word);
		nextword.erase(i,1);
		if (!check_success(nextword)) {
			cachemap[word] = true;
			return true;
		}
	}
	cachemap[word] = false;
	return false;
}

int who(string word)
{
	return int(check_success(word));
}

int main(int argc, char** argv)
{
	char* tests[] = {"phqghumeaylnlfd",
		"xfircvscxggbwkf",
		"nqduxwfnfozvsrt",
		"kjprepggxrpnrvy",
		"stmwcysyycqpevi",
		"keffmznimkkasvw",
		"srenzkycxfxtlsg",
		"ypsfadpooefxzbc",
		"oejuvpvaboygpoe",
		"ylfpbnpljvrvipy",
		"amyehwqnqrqpmxu",
		"jjloovaowuxwhms",
		"ncbxcoksfzkvatx",
		"dknlyjyhfixjswn",
		"kkufnuxxzrzbmnm",
		"gqooketlyhnkoau",
		"gzqrcddiuteiojw",
		"ayyzpvscmpsajlf",
		"vgubfaaovlzylnt",
		"rkdcpwsrtesjwhd"};
	for (int index = 0; index < sizeof(tests)/sizeof(char*); index++)
		printf("%s --> %d\n", tests[index], who(tests[index]));
	getchar();
	return 0;
}

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

下面是kabam game server(backend) c++编程测试题(前面都通关了,最后卡在跟老外项目制作人的英语交流上铩羽而归)

Question 2

Read the comments and code for the data structures in the file OrderedDatabase.cpp then implement these functions:
A) OrderedDatabase::LinkInOrder
B) OrderedDatabase::SwapRecordValue
C) TestOrderedDatabase

Follow these coding guidelines:
1) All code needed to complete the task must be in the file provided.
2) Do not change the function prototypes or class variable declarations.
3) You can write additional helper functions to complete the task.
4) Include appropriate comments in your code.
5) Ensure that your code compiles and runs without crashing for all valid input.

6) Use asserts (defined in <assert.h>) to enforce your assumptions

#include <assert.h>
#include <stdio.h>

///
// struct Record
// In this question we will work with a database of data records. Each record holds
// an integer value. These values will be random, and not necessarily unique. 
// The records also contains a pointer m_next which will be used to link records together.
///
struct Record
{
	int m_value;     // Value stored in the record.
	Record* m_next;  // Pointer used to link the records.
};

///
// class Database
// The records are stored in a database. The database consists of a variable 
// number of arrays of records. The number of arrays is given by m_arrayCount.
// Each array must have the same number of records in it, given by m_arraySize.
//
// For example, this code initializes a database with 3 arrays that each contain 5 records.
// The m_value fields are just random.
//
// Record array0[5]  = {{  4, 0}, { 89, 0}, {189, 0}, { 76, 0}, {200, 0}};
// Record array1[5]  = {{205, 0}, { 37, 0}, { 66, 0}, {105, 0}, { 13, 0}};
// Record array2[5]  = {{ 13, 0}, {241, 0}, {158, 0}, { 22, 0}, {140, 0}};
// Record* arrays[3] = {array0, array1, array2};
// Database database(3, 5, arrays);
///
class Database
{
public:
	Database(int arrayCount, int arraySize, Record** arrays)
		: m_arrayCount(arrayCount), m_arraySize(arraySize), m_arrays(arrays)
	{
	}

	Record** m_arrays;
	int m_arrayCount;
	int m_arraySize;
};

///
// class OrderedDatabase
// This subclass of Database keeps all of the records in order by their m_value variable, 
// from smallest to largest. The records stay in their original location in memory, but are 
// linked together in order using their m_next pointer. The first record in the ordering,
// i.e. the one with the smallest m_value, is pointed to by m_firstRecord.
//
// The function LinkInOrder initializes the links between the records.
// The function SwapRecordValue replaces one value in the database with another.
///
class OrderedDatabase : public Database
{
public:
	OrderedDatabase(int arrayCount, int arraySize, Record** arrays)
		: Database(arrayCount, arraySize, arrays)
	{
		LinkInOrder();
	}

	void LinkInOrder();

	void SwapRecordValue(int oldValue, int newValue);

	void PrintValues();

	Record* m_firstRecord;

private:
	Record*	FetchPrevRecord(int value);

};

///
// Part A)
//
// Name:   void OrderedDatabase::LinkInOrder();
//
// Input:  
//         The database must be initialized and have m_arrays, m_arrayCount and m_arraySize values set.
//         Make no assumptions about how the Record m_next pointers are initially set.
//
// Output: 
//         The function should use the m_next pointers of the database records to link them together
//         in sorted order by m_value, from smallest to largest. It should set m_firstRecord to be a 
//         pointer to the first record in the chain. The last record in the chain should have
//         m_next == 0.
//
//         Eg:
//         For the example Database shown above, the OrderedDatabase would be linked like this:
//         m_firstRecord->4->13->13->22->37->66->76->89->105->140->158->189->200->205->241->0
//
// Specifications:
//     This code will run only at initialization time, so it is not called very often. 
//     Your algorithm should complete in O(n2) time and use O(1) memory.
//     Your code should not crash as long as the database meets the specifications above.
///
void  
OrderedDatabase::LinkInOrder()
{
	//initialize m_next
	for (int i = 0; i < m_arrayCount; i++) {
		for(int j = 0; j < m_arraySize; j++) {
			((*(m_arrays+i))+j)->m_next = 0;
		}
	}
	m_firstRecord = 0; //the beginning of the sorted chain
	Record* nextPtr = 0; //the end of the sorted chain
	for (int count = 0; count < m_arrayCount*m_arraySize; count++) {
		Record* smallPtr = 0; //the smallest record of the unsorted ones
		for (int i = 0; i < m_arrayCount; i++){
			for (int j = 0; j < m_arraySize; j++) {
				Record* tmpPtr = (*(m_arrays+i))+j;
				//found the first unsorted record
				if (!smallPtr && (tmpPtr->m_next==0) && (tmpPtr!=nextPtr)) {
					smallPtr = tmpPtr;
					continue;
				}
				//found the smaller record in the unsorted ones
				if (smallPtr && (tmpPtr->m_next==0) && (tmpPtr!=nextPtr) && (tmpPtr->m_value<smallPtr->m_value)) {
					smallPtr = tmpPtr;
				}
			}
		}
		assert( smallPtr );
		if (!m_firstRecord) {
			nextPtr = m_firstRecord = smallPtr;
		} else {
			nextPtr->m_next = smallPtr;
			nextPtr = smallPtr;
		}
	}
}


///
// Part B)
//
// Name:   void OrderedDatabase::SwapRecordValues(int oldValue, int newValue);
//
// Input:  
//         Assuming that the database is already linked using the LinkInOrder() function.
//
// Output: 
//         The function should find all records that have m_value equal to oldValue and change
//         their value to newValue. The links in the database should be fixed to maintain the sorted
//         ordering.
//
//         Eg:
//         If the database is linked up so like this:
//         m_firstRecord->4->13->13->22->37->66->76->89->105->140->158->189->200->205->241->0
//         
//         Calling:
//         database.SwapRecordValue(13, 2);
//
//         Will result in the database being like this:
//         m_firstRecord->2->2->4->22->37->66->76->89->105->140->158->189->200->205->241->0
//
// Specifications:
//     This function will be called on a large database several times per frame of the 
//     videogame, so performance is critical. It needs to be as fast as possible. 
//     Your algorithm should use O(1) memory.
//     Your code should not crash as long as the database meets the specifications above.
///
void 
OrderedDatabase::SwapRecordValue(int oldValue, int newValue)
{
	if (!m_firstRecord || (m_firstRecord->m_value>oldValue) || (oldValue==newValue))
		return;

	//look for records equal to oldValue
	Record* oldPrev = 0; //old pos
	Record* newPrev = 0; //new pos
	Record* ptr = m_firstRecord; //record to analyze
	bool foundNewPrev = false;	//avoid the duplicate seekings
	while(ptr && ptr->m_value<=oldValue) {
		if (ptr->m_value == oldValue) {
			//look for newposition
			if (!foundNewPrev) {
				newPrev = FetchPrevRecord(newValue);
				foundNewPrev = true;
			}
			//change value
			ptr->m_value = newValue;
			//"pos unchanged" or "new pos is old pos's left side" or "new pos is old pos's right side"
			if ((newPrev==oldPrev) || (newPrev&&(newPrev->m_next==ptr||newPrev==ptr))) {
				;
			}else {
				//delete from old position
				if (!oldPrev) {
					m_firstRecord = ptr->m_next;
				} else {
					oldPrev->m_next = ptr->m_next;
				}
				//add to new position
				if (!newPrev) {
					ptr->m_next = m_firstRecord;
					m_firstRecord = ptr;
				}else {
					ptr->m_next = newPrev->m_next;
					newPrev->m_next = ptr;
				}
			}
			//ptr for next loop
			if (!oldPrev) {
				ptr = m_firstRecord;
			}else {
				ptr = oldPrev->m_next;
			}
			//not found
		} else {
			oldPrev = ptr;
			ptr = ptr->m_next;
		}
	}
}


///
//
//look for the biggest record of the ones whose value < "value"
//
///
Record*
OrderedDatabase::FetchPrevRecord(int value)
{
	assert(m_firstRecord);
	if (m_firstRecord->m_value >= value)
		return 0;
	Record* newPrev = m_firstRecord;
	while (newPrev->m_next && newPrev->m_next->m_value<value)
		newPrev = newPrev->m_next;
	return newPrev;
}

void
OrderedDatabase::PrintValues()
{
	if (m_arrayCount*m_arraySize == 0) {
		printf("empty\n\n");
		return;
	}

	printf("unsorted values:\n");
	for(int i = 0; i < m_arrayCount; i++) {
		for (int j = 0; j < m_arraySize; j++) {
			printf("%10d", ((*(m_arrays+i))+j)->m_value);
		}
		printf("\n");
	}

	printf("sorted values:\n");
	Record* ptr = m_firstRecord;
	int index = 1;
	while (ptr) {
		printf("%10d", ptr->m_value);
		if (index%m_arraySize == 0)
			printf("\n");
		ptr = ptr->m_next;
		index++;
	}
	printf("\n");
}

///
// Part C)
//
// Name: void TestOrderedDatabase(void);
//
//
// Specifications:
//     Write test cases for the LinkInOrder and SwapRecordValue functions in OrderedDatabase 
//     to show that the functions meet the specifications.
///
void 
TestOrderedDatabase()
{
	OrderedDatabase* db = 0;

	{
		db = new OrderedDatabase(1, 0, 0);
		db->PrintValues();
		delete db;
	}

	{
		db = new OrderedDatabase(0, 0, 0);
		db->PrintValues();
		delete db;
	}

	{
		Record r1[3] = {{1,0}, {3,0}, {2,0}};
		Record r2[3] = {{3,0}, {6,0}, {5,0}};
		Record* records[2] = {r1, r2};
		db = new OrderedDatabase(2, 3, records);
		db->PrintValues();
		printf("swap 3 to 9...\n");
		db->SwapRecordValue(3, 9);
		db->PrintValues();
		printf("swap 9 to -1...\n");
		db->SwapRecordValue(9, -1);
		db->PrintValues();
		printf("swap 6 to 6...\n");
		db->SwapRecordValue(6, 6);
		db->PrintValues();
		printf("swap 100 to 10...\n");
		db->SwapRecordValue(100, 10);
		db->PrintValues();
		delete db;
	}
	
	{
		Record r1[1] = {{1,0}};
		Record* records[1] = {r1};
		db = new OrderedDatabase(1, 1, records);
		db->PrintValues();
		printf("swap 3 to 9...\n");
		db->SwapRecordValue(3, 9);
		db->PrintValues();
		printf("swap 1 to 100...\n");
		db->SwapRecordValue(1, 100);
		db->PrintValues();
		printf("swap 100 to 10...\n");
		db->SwapRecordValue(100, 10);
		db->PrintValues();
		delete db;
	}
}

// #define MAIN_DEBUG
// #ifdef MAIN_DEBUG
// int main(int argc, char** argv)
// {
// 	TestOrderedDatabase();
// 	getchar();
// 	return 0;
// }
// #endif

Question 4
This question is optional for junior programmers. Applicants for senior programming position MUST complete this question.

Read the comments and code for the data structures in the file ReverseWords.cpp then implement these functions:
A) ReverseWords
B) ReverseWordsInPlace
C) TestReverseWords

Follow these coding guidelines:
1) All code needed to complete the task must be in the file provided.
2) Do not change the function prototypes or class variable declarations.
3) You can write additional helper functions to complete the task.
4) Include appropriate comments in your code.
5) Ensure that your code compiles and runs without crashing for all valid input.
6) Use asserts (defined in <assert.h>) to enforce your assumptions

#include <assert.h>
#include <stdio.h>

///
// Part A)
//
// Name:   void ReverseWords(char* inputString, char* outputString);
//
// Input:  
//          inputString:  A NULL terminated character string consisting of words separated 
//                        by a single whitespace.
//          outputString: A buffer with enough space to store a copy of inputString.
//
// Output: 
//         outputString should have the same words as inputString, but with the words in reverse order. 
//         The letters in each word should not be reversed.
//
//         For example: 
//           char* inputString = "Hello this is my BalancedWorlds programming TEST";
//           char  outputString[256];
//           ReverseWords(inputString, outputString);
//         Will result in outputSting being:
//           "TEST programming BalancedWorlds my is this Hello"
//
// Important Specifications:
//     Your code should work with the character data directly. Do NOT use the C++ string class or 
//     any standard library string manipulation functions such as sprintf, sscanf, etc.
//
//     Your algorithm should complete in O(n) time and use O(1) memory. In other words, you may only 
//     use a constant amount of memory that does NOT depend on the size of the string or lengths
//     of the words. The memory should be declared on the stack, not using dynamic allocations. 
///
void ReverseWords(const char* inputString, char* outputString)
{
	if (!inputString)
		return;

	//int len = strlen(inputString);
	int len = 0;
	while (*(inputString+len))
		len++;
	if (len == 0) {
		*outputString = '\0';
		return;
	}

	char* writePtr = outputString;
	int start = -1; //the beginning of word
	//scan inputString from end to begging
	for (int cursor = len - 1; cursor >= 0; cursor--) {
		char c = *(inputString+cursor);
		//looking for the beginning of word
		if (start == -1) {
			if (c != ' ') { //found
				start = cursor;
			} else { //not found
				*writePtr = c;
				writePtr++;
			}
		}
		//looking for the end of word
		if (start != -1) {
			if ((c==' ') || (cursor==0)) { //found
				//calc word length and read position
				int realCursor;
				int wordLen;
				if (cursor != 0) {
					realCursor = cursor + 1;
					wordLen = start - cursor;
				} else {
					realCursor = cursor;
					wordLen = start - cursor + 1;
				}
				//copy the word from inputString to outputString
				for (int i = 0; i < wordLen; i++) {
					*writePtr = *(inputString + realCursor + i);
					writePtr++;
				}
				//copy the blank char
				if (cursor != 0) {
					*writePtr = c;
					writePtr++;
				}
				//reset start
				start = -1;
			} else { //not found
				;
			}
		}
	}
	*writePtr = '\0';
}

void ReverseChars(char* begin, char* end)
{
	char c;
	while (begin < end)
	{
		c = *begin;
		*begin++ = *end;
		*end-- = c;
	}
}

///
// Part B)
//
// Name:   void ReverseWordsInPlace(char* string);
//
// Input:  
//          string:  A NULL terminated character string consisting of words separated 
//                   by a single whitespace.
//
// Output: 
//          The same as ReverseWords(), except that the result is returned in inputString.
//
// Specifications:
//     Your code should work with the character data directly. Do NOT use the C++ string class or 
//     any standard library string manipulation functions such as sprintf, sscanf, etc. 
//
//     Your algorithm should complete in O(n) time and use O(1) memory. In other words, you may only 
//     use a constant amount of memory that does NOT depend on the size of the string or lengths
//     of the words. The memory should be declared on the stack, not using dynamic allocations. 
///
void ReverseWordsInPlace(char* inputString)
{
	if (!inputString)
		return;

	//int len = strlen(inputString);
	int len = 0;
	while (*(inputString+len))
		len++;
	if (len == 0)
		return;

	int wordStart = -1;
	char* ptr = inputString;

	//reverse chars in word
	for (ptr = inputString; *ptr; ptr++) {
		//look for the beginning of word
		if (wordStart == -1) {
			if (*ptr != ' ') //found
				wordStart = ptr - inputString;
		}
		//look for the end of word
		if (wordStart != -1) {
			if (*ptr == ' ') { //found
				ReverseChars(inputString+wordStart, ptr-1);
				wordStart = -1;
			}
		}
	}
	assert(!*ptr);
	if (wordStart != -1)
		ReverseChars(inputString+wordStart, ptr-1);

	//reverse chars in string
	ReverseChars(inputString, ptr-1);
}

void ReverseAndPrintf(const char* src, char* dst)
{
	ReverseWords(src, dst);
	printf("src :\"%s\"\n", src);
	printf("dst :\"%s\"\n", dst);
	ReverseWordsInPlace(dst);
	printf("dst2:\"%s\"\n", dst);
	printf("\n");
}

///
// Part C)
//
// Name: void TestReverseWords(void);
//
//
// Specifications:
//     Write test cases for both ReverseWords and ReverseWordsInPlace to show that 
//     the functions meet the specifications.
///
void TestReverseWords(void)
{
	{
		const char* src = "hello world !";
		char dst[14];
		ReverseAndPrintf(src, dst);
	}
	{
		const char* src = "a";
		char dst[2];
		ReverseAndPrintf(src, dst);
	}
	{
		const char* src = "a ";
		char dst[3];
		ReverseAndPrintf(src, dst);
	}
	{
		const char* src = "a  ";
		char dst[4];
		ReverseAndPrintf(src, dst);
	}
	{
		const char* src = " a";
		char dst[3];
		ReverseAndPrintf(src, dst);
	}
	{
		const char* src = " ";
		char dst[2];
		ReverseAndPrintf(src, dst);
	}
	{
		const char* src = "";
		char dst[1];
		ReverseAndPrintf(src, dst);
	}
	{
		const char* src = "a b  c ";
		char dst[8];
		ReverseAndPrintf(src, dst);
	}
}

// #define MAIN_DEBUG
// #ifdef MAIN_DEBUG
// int main(int argc, char** argv)
// {
// 	TestReverseWords();
// 	getchar();
// 	return 0;
// }
// #endif

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

c切割字符和窜并存入数组

#include <string.h>
#include <stdlib.h>
#include <assert.h>

char ** array_string_split(const char *s, const char *sep)
{
	//分隔符不能是'\0'
	int buffer_len = 4;
	char** buffer = (char**)malloc(sizeof(char*)*buffer_len);
	int index = 0;
	char* base_str = strdup(s);
	char* str = base_str;
	while (str != NULL) {
		char* tmp_token = strsep(&str, sep);
		if (strlen(tmp_token) > 0) {
			if (index >= buffer_len-1) {
				buffer_len *= 2;
				char** tmp_buffer = (char**)malloc(sizeof(char*)*buffer_len);
				assert(tmp_buffer);
				memcpy(tmp_buffer, buffer, index*sizeof(char*));
				free(buffer);
				buffer = tmp_buffer;
			}
			*(buffer+index) = strdup(tmp_token);
			index++;
		}
	}
	*(buffer+index) = NULL;
	free(base_str);
	return buffer;
}

int array_string_search(/*const*/ char *array[], const char *needle)
{
	int index = 0;
	while (array[index] != NULL) {
		if (strcmp(array[index],needle) == 0)
			return index;
		index++;
	}
	return -1;
}

void array_string_free(/*const */char *array[])
{
	char** ptr = array;
	while(*ptr != NULL) {
		free(*ptr);
		ptr++;
	}
	free(array);
}

#ifdef TEST
#include <stdio.h>
int main(int argc, char** argv)
{
	char str[1024];
	char sep[100];
	printf("input your string:\n");
	scanf("%s", str);
	printf("inbput your sep:\n");
	scanf("%s",sep);
	

	char** tokens = array_string_split(str,sep);
	char** token = tokens;
	while(*token != NULL) {
		printf("%s\n",*token);
		token++;
	}
	char tmp[100];
	while(1) {
		printf("find (input 'exit!' to break.) > ");
		scanf("%s",tmp);
		if (strcmp(tmp,"exit!") == 0)
			break;
		printf("index = %d.\n",array_string_search(tokens,tmp));
	}

	array_string_free(tokens);
}
#endif
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

linux c++ -> ls

#include <dirent.h>
void ls(const char* path, vector<string>& files)
{
        DIR* dp;
        dirent *d;
        dp = opendir(path);
        while ((d=readdir(dp)) != NULL){
                if (!string(d->d_name).compare(".") || !string(d->d_name).compare(".."))
                        continue;
                files.push_back(string(d->d_name));
        }
}
readdir非线程安全,应该改成readdir_r


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值