算法学习过程中遇到的问题与求解(自用)

//求大小为10的数组中不重复的元素个数(不用bool数组的解法)
sort(a,a+10);
for(int i = 1;i<a.size();i++)
{
    if(a[i] != a[i-1])
        sum++;
}

UVA101题
1.先输入int型 后输入string型的题目,输入int后要有getchar

2.注意第一步返回ret1=0 说明此情况为特例,应立即break

{int ret1 = analyse();
 if(!ret1)
     break;
 int ret2 = findab();
 if(!ret2)
     continue;
}

3.图为利用find与substr切割字符串的解法,附带stringstream的使用

		pos = 0;
        stringstream t1,t2;
        tempNum = temp.find(' ',pos);
        tempF = temp.substr(pos,tempNum - pos);
        pos = tempNum + 1;
        tempNum = temp.find(' ',pos);
        t1 << (temp.substr(tempNum - pos));
        t1 >> a;
        pos = tempNum + 1;
        tempNum = temp.find(' ',pos);
        tempS = temp.substr(pos,tempNum - pos);
        pos = tempNum + 1;
        t2 << temp.substr(pos,temp.size()-pos);
        t2 >> b;

4.图下的方式(接3)能省去先输入后切割还要分析的麻烦(挨个输入)

while (cin >> Com1)
	{
		if (Com1 == "quit")
			break;
		string  Com2;
		int a, b;
		cin >> a >> Com2 >> b;

		if (poss[a].x == poss[b].x)
			continue;
		if (Com1 == "move")
			MoveBack(a);
		if (Com2 == "onto")
			MoveBack(b);
		MoveAll(a, b);
	}

5.可以在建立vector数组的同时,建立一个速查表,以struct node为元素,每次更改vector后更新速查表元素。
vector的resize函数可以迅速切断vector后面一段的元素

blocks[local.x].resize(local.y + 1);//重置大小(删除方块堆后面的方块)

1.关于链表:
迅速找到中间节点:快慢指针,一个指针一次走一步,一个指针一次走两步。

UVA11988
STL中链表为list
可以使用迭代器iterator=list.begin()|end()来控制输入符在begin还是end
(我的做法,设计两个string,‘【’开始向temp输入 ‘】’开始讲temp回归到all的最前端)

UVA12657
1.遇到问题:将一个数移到另一个数左边,使用迭代器的话,删除元素可能会使迭代器移动,因为迭代器无法比较大小,所以不稳定,不知道什么时候移动什么时候不移动
可以采用静态链表&&双向链表,查找元素为O(1)的复杂度,设置pre和nxt两个数组
2.翻转链表可以不急着动,只要标记状态即可,比如说现在是翻转状态的将a放到b左边,即放到右边即可,逻辑顺序不会变,最后统一对不同状态讨论,题目让求奇数和,则顺序奇数和或逆序奇数和。
3.设置头结点和尾结点,不能只设置头结点不设置尾结点,不然翻转的话尾结点就变成了头结点,要对称。
4.求奇数位的和,和偶数位的和,可以用总和减,免去循环。

UVA514
注意,栈等stl的调用,比如top函数,必须在栈中有元素的前提下才可以进行

        if(!src.empty())
        {
            if(squl[cnt] == src.top())
            {
                cnt++;
                src.pop();
                continue;
            }
        }

有先后顺序
如果直接

if(!src.empty()&&squl[cnt] == src.top)

会报错(不过有短路原理应该也可,没试)

UVA442
关于栈
注意谁先出谁后出

mtx temp2 = allStack.top();
allStack.pop();
mtx temp1 = allStack.top();
allStack.pop();

还有,用字母作下标表示的数组
不用alpha2int函数来转换,直接减去‘A’或‘a’即可
还有 有时候考虑的太多了,题目没有那么多情况。

UVA12100
牺牲空间换时间做法:

//bool curIsMax()//当前的是否是最大的,是否可以执行?
//{
//    int cur = que[0].num;
//    for(int i = 1;i < que.size();i++)
//    {
//        if(cur < que[i].num)
//        {
//            return false;
//        }
//    }
//    return true;
//}

我的做法↑普通遍历找最大

老师的做法↓
复制初始数组

a.pushback(intputNum);
b.pushback(intputNum);
sort(b.begin(),b.end(),greater<int>());//不写函数默认升序。
int w = 0;
b[w++]即为最大值

unique函数去重
使用方法(一般为先排序后去重)
unique函数返回尾地址。

    sort(arr,arr+n);
    int n2 = unique(arr,arr+n)-arr;
    for(int i = 0;i<n2;i++)
    {
        cout << arr[i] << ' ';
    }

如何存储如下的数据?

0001000
0001000
0001111
0001000
0001000
0001000
1111111

n*n的矩阵,n未知?

string arr[205];//字符串数组

第一行特殊存储

    cin >> arr[0];
    for(int i = 1;i < arr[0].size();i++)
    {
        cin >> arr[i];
    }

即可

P1830
用一个二维数组存储两个点坐标,不如用一维数组,分开存储即可。
有些不用二维数组的。
要求:存储每个点被轰炸次数:
二维数组arr[105][105]
数组中存储的数代表被轰炸次数。
不如:
4个一维数组存储每次轰炸的左上和右下顶点坐标

    for(int i = 1;i <= x;i++)
    {
        cin >> arrx1[i] >> arry1[i] >> arrx2[i] >> arry2[i];
    }

之后

if(tempx >= arrx1[j] && tempx <= arrx2[j] && tempy >= arry1[j] && tempy <= arry2[j])
{
     cnt++;
     times = j;
}//关键代码

在输入被检测坐标的时候根据四个一维数组来判断轰炸次数。

关于kmp
求next数组
其实是求之前的元素最多的前缀等于后缀,和这个字符本身无关。

以下是模式匹配出所有情况。

string s1,s2;
    cin >> s1 >> s2;
    string::size_type pos = 0;
    while((pos = s1.find(s2,pos))!=string::npos)
    {
        cout << pos+1 << endl;
        pos++;
    }

UVA401
一个特别奇妙的方法:
记录每个字母与数字的镜像数
不再需要键值对map 这个stl
直接用string

string str = "A   3  HIL JM O   2TUVWXY51SE Z  8 "

检测两个字符是否匹配↓

	if(isupper(c))
    {
        if(str[c-'A'] == d)
            return true;
        else
            return false;
    }
    else
    {
        if(str[c-'0'+25] == d)
            return true;
        else
            return false;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值