笔试常见编程题

目录

1、简化Unix路径

2、石块向下掉落

3、最大连续子数组

4、最长递增子序列

5、循环小数计算循环节和循环节长度

6、压缩空格和字符串

7、只压缩空格

8、排列组合算法

9、大数相加、相减

10、十进制数转换为任意进制、任意进制转换为10进制数

11、反转链表

12、字符串转数字与数字转字符串方式


1、简化Unix路径

/*********************leetCode72简化Unix路径*****************/

#include 
#include 
#include 

using namespace std;

string simplifyPath(string path)
{
	if (path.empty())
		return "";

	stack ss;
	for (int i = 0; i < path.size();)
	{
		//跳过斜线‘/'
		while (i < path.size() && '/' == path[i])
			++i;
		string s = "";
		while (i < path.size() && path[i] != '/')
			s += path[i++];
		//如果是".."则弹出栈,否则入栈
		if (".." == s && !ss.empty())
			ss.pop();
		else if (s != "" && s != "." && s != "..")
			ss.push(s);
	}
	if (ss.empty())
		return "/";

	string s = "";
	while (!ss.empty())
	{
		s = "/" + ss.top() + s;
		ss.pop();
	}
	return s;
}

int main()
{
	//path = "/home/", => "/home"
	//path = "/a/./b/../../c/", => "/c"
	//string path = "/home/";
	string path = "/a/./b/../../c/";
	cout << simplifyPath(path) << endl;

    return 0;
}

2、石块向下掉落

/********************石块向下掉落******************/
#include 
#include 
#include 

using namespace std;

void stoneFalling(vector &vec)
{
	int N, M;
	cin >> N >> M;
	//vector vec;

	for (int i = 0; i < N; i++)
	{
		string s;
		cin >> s;

		vec.push_back(s);
	}

	for (int j = 0; j < M; j++)
	{
		int i = N - 1;
		for (; i >= 0; i--)
		{
			if (vec[i][j] != 'x')
				vec[i][j] = '.';
			else
				break;
		}
		int k = i - 1;
		for (int m = i - 1; m >= 0; m--)
		{
			if (vec[m][j] == 'o' && vec[k][j] == '.')
			{
				vec[k--][j] = vec[m][j];
				vec[m][j] = '.';
			}
			else if (vec[m][j] == 'x')
				k = m - 1;
			else if (vec[k][j] == 'o')
			{
				k--;
			}
		}
	}

	for (int i = 0; i < N; i++)
	{
		cout << vec[i] << endl;
	}
}

int main()
{
    vector P = { "ooxo", "oox.", ".x.o", "xooo"};
    stoneFalling(P);
    return 0;
}

3、最大连续子数组

/*********************最大连续子数组********************/
#include 
#include 
#include 

using namespace std;

int getMaxConArray(vector & array)
{
	if (array.empty())
		return 0;

	int len = array.size();
	int sum = array[0];
	int thisSum = array[0];
	for (int i = 1; i < len; ++i)
	{
		thisSum = max(thisSum + array[i], array[i]);
		if (sum < thisSum)
			sum = thisSum;
	}
	return sum;
}

int main()
{
	vector A = { 1, -2, 3, 5, -3, 2 };		//输出8
	vector B = { 0, -2, 3, 5, -1, 2 };		//输出9
	vector C = { -9, -2, -3, -5, -3};		//输出-2

	cout << getMaxConArray(C) << endl;
    return 0;
}

4、最长递增子序列

/********************动态规划思想O(n2)******************/
#include 
#include 

using namespace std;

vector getLongSubsequ(vector & str)
{
	if (str.empty())
		return{};

	const int len = str.size();
	vector dp(len, 1);
	for (int i = 1; i < len; ++i)
	{
		for (int j = 0; j < i; ++j)
		{
			if (str[i] > str[j] && dp[i] < dp[j] + 1)
			{
				dp[i] = dp[j] + 1;
			}
		}
	}

	int max = dp[0];
	int index = 0;
	for (int i = 1; i < len; ++i)
	{
		if (max < dp[i])
		{
			max = dp[i];
			index = i;
		}
	}
	cout << "最大长度为:" << max << endl;

	vector seque(max + 1, 0);
	seque[max] = str[index];
	for (int i = index - 1; i > 0; --i)
	{
		if (str[index] > str[i] && dp[index] == dp[i] + 1)
		{
			seque[--max] = str[i];
			index = i;
		}
	}

	for (auto a : seque)
		cout << a << " ";
	cout << endl;
	return dp;
}

int main()
{
    vector A = { 1, -1, 2, -3, 4, -5, 6, -7 };		//输出1246
	//vector B = { 2, 1, 5, 3, 6, 4, 8, 9, 7 };		//输出13489
    getLongSubsequ(A);
    return 0;
}

5、循环小数计算循环节和循环节长度

/********************UVA202循环小数计算循环节和循环节长度******************/
const int MAXN = 30000 + 5;
int res[MAXN];		//存放出现次数
int arr[MAXN];		//存放小数部分
int v[MAXN];		//循环开始位置

void getCircleNumbers(int a, int b)
{
	memset(res, 0, sizeof(res));

	a = a%b * 10;
	int index = 1;

	while (res[a] == 0)
	{
		res[a] = 1;
		v[a] = index;
		arr[index++] = a / b;
		a = a%b * 10;
	}

	cout << "v[a]:" << v[a] << endl;
	cout << "index:" << index << endl;

	for (int i = v[a]; i < index; ++i)
		cout << arr[i];
	cout << endl;
}

int main()
{
    /*******UVA202循环小数计算循环节和循环节长度***********/
	//getCircleNumbers(5, 7);		//5/7 = 0.714285 输出循环节: 714285 长度:6
	//getCircleNumbers(1, 250);	    //1/250 = 0.004		0		1;
	getCircleNumbers(300, 31);	//300/31 = 9.677419354838709 677419354838709 15
	//getCircleNumbers(2, 15);	    //2/15 = 0.133333...	2 
    return 0;
}

6、压缩空格和字符串

/******************压缩空格和字符串**********************/
#include 
#include 
#include 

using namespace std;

string compressSpaces(string str)
{
	if (str.empty())
		return{};

	int len = str.size();
	char temp = str[0];
	int count = 1;
	string last;
	for (int i = 1; i <= len; ++i)
	{
		if (str[i] == temp)
			count++;
		else if (str[i] != temp || str[i] == '\0')
		{
			if (temp != ' ')
			{
				//stringstream ss;    //数字转字符串第一种方式,数字特别大时不推荐
				//ss << count;
				//last += ss.str() + temp;
				last += to_string(count) + temp;    //第二种方式
			}
			else
				last += temp;

			temp = str[i];
			count = 1;
		}
	}
	return last;
}

int main()
{
	string str = "aaabcccc    sssfff";		//3a1b4c 3s3f
	cout << compressSpaces(str) << endl;

    return 0;
}

7、只压缩空格

/**********************只压缩空格**********************/
#include 

using namespace std;

void FormatString(char str[], int len)
{
	if (str == NULL || len <= 0)
		return;

	int i = 0, j = 0;
	while (str[i] == ' ')//开头的空格
		i++;
	while (str[i] != '\0')
	{
		if (str[i] == ' ' && (str[i + 1] == ' ' || str[i + 1] == '\0'))
		{
			//中间或者结尾的空格
			i++;
			continue;
		}
		str[j++] = str[i++];
	}
	str[j] = '\0';
}

int main()
{
	char a[] = {"a  s  d  f  g  h  j  k  l"};
	FormatString(a, 10);
	cout << a << endl;

    return 0;
}
	

8、排列组合算法

/**********************排列算法递归实现***********************/
#include 
#include 

using namespace std;

void permutation(char* pStr, char* pBegin)
{
    assert(pStr && pBegin);
    
    if(*pBegin == '\0')
        cout << pStr << endl;
    else
    {
        for(char* pCh = pBegin; *pCh != '\0'; pCh++)
        {
            swap(*pBegin, *pCh);
            permutation(pStr, pBegin + 1);
            swap(*pBegin, *pCh);
        }
    }
}

int main()
{
    char str[] = "abc";
    permutation(str, str);

    return 0;
}

9、大数相加、相减

#include 
#inlcude 

using namespace std;

string bigNumAdd(string num1, string num2)    //专门处理字符串长度相等的情况
{
    string sum;
    int flag = 0;
    for(int i = num1.size() - 1; i >= 0; --i)
    {
        int b = num1[i] - '0' + num2[i] - '0' + flag;
        if(b > 9)
        {
            b -= 10 + '0';
            sum.push_back(b);
            flag = 1;
        }
        else
        {
            sum.push_back(b);
            flag = 0;
        }
    }
    if(flag != 0)
        sum.push_back(flag + '0');

    return string(sum.rbegin(), sum.rend());
}

string addStrings(string num1, string num2)    //处理字符串长度不等的情况
{
    if(num1.size() == num2.size())
    {
        return bigNumAdd(num1, num2);
    }
    else if(num1.size() < num2.size())
    {
        swap(num1, num2);
    }

    size_t len = num1.size() - num2.size();
    string num3(len, '0');
    num2 = num3 + num2;
    
    return bigNumAdd(num1, num2);
}


int main()
{
    string num1, num2;
    while(cin >> num1 >> num2)
    {
        cout << addString(num1, num2) << endl;
    }
    
    return 0;
}

10、十进制数转换为任意进制、任意进制转换为10进制数

/***********************将一个10进制的数n转换成r进制数******************/
#include 

using namespace std;

int main()
{
	int n, r;	//r表示要转的进制
	cin >> n >> r;
	int i = 0, c, a[100];

	while (n != 0)
	{
		c = n%r;
		a[i++] = c;
		n = n / r;
	}
	
	for (int j = i - 1; j >= 0; --j)
	{
		if (a[j] >= 10)
			cout << char('A' + a[j] - 10);
		else
			cout << a[j];
	}

	cout << endl;
    return 0;
}
/**************************任意进制数转换为10进制数*********************/
#include 

using namespace std;

int main()
{
	string n;	//r表示进制,n为要转换的数
	int r;
	cin >> n >> r;
	int ans = 0, i = 0;
	while (n.size() != i)
	{
		ans *= r;
		ans += n[i++] - '0';
	}

	cout << ans << endl;

    return 0;
}

11、反转链表

#include 

using namespace std;

struct Node
{
	int value;
	Node* next;
};

Node* ReverseList(Node* pHead)    //定义三个指针,分别指向当前,后一个,前一个位置
{
	if (pHead == nullptr)
		return;

	Node* pReverseHead = NULL;
	Node* pPre = NULL;
	Node* pNode = pHead;
	while (pNode != NULL)
	{
		Node* pNext = pNode->next;
		if (pNext == NULL)
			pReverseHead = pNode;

		pNode->next = pPre;
		pPre = pNode;
		pNode = pNext;
	}
	return pReverseHead;
}

12、字符串转数字与数字转字符串方式

/***************基于C++11*****************/
//1、字符串转数字,利用库函数
#include 

int stoi(const std::string &str);
long stol(const std::string &str);
double stod(const std::string &str);

//2、将其他类型转为字符串
string to_string(typename val);    //将其他类型转换为string


/***************C++11之前*****************/
#include 

//1、字符串转数字
int atoi(const char * str);
double atof(const char * str);
long int atol(const char * str);

//2、字符串转数字,利用stringstream流
#include 
#include 

int str2num(const string str)
{
    stringstream ss(str);
    int num;
    ss >> num;
return num;
}
//数字转字符串
string num2str(const int num)
{
    stringstream ss;
    ss << num;
    return ss.str();
}

13、单词反转

/***********************单词反转****************/
//例如:输入“I am a student.”输出:“student. a am I”

#include 
#include 

using namespace std;

void reverseWord(string &str, int low, int high)
{
    while (low < high)
	{
		swap(str[low++], str[high--]);
	}
}

int main()
{
	string str = "I am a student."; //输出“student. a am I"

	int i = 0;
	int j = i;
	for (; i <= str.size(); ++i)    //反转每个单词
	{
		if (str[i] == ' ' || str[i] == '\0')
		{
			reverse(str, j, i - 1);
			j = i + 1;
		}
	}
	reverse(str, 0, str.size()-1);    //反转整个句子

	cout << str << endl;

    return 0;
}
    

附录:C++11产生随机数,随机浮点数,各种分布随机数方法1和方法2。

你可能感兴趣的:(算法学习相关问题)