《算法笔记上机实验指南》第4章 入门篇(2)---算法初步 4.2散列

pat A1084


题意:

输入:

1.输入字符串s1,s2

输出:

1.输出s2中没有s1的字符,并且必须是大写,且不能重复



解题思路1:

              1.由于要有总排名,考场排名...所以在定义结构时将这些内容加进去                  2.cmp排序要求是:成绩不同,按照成绩降序排列,否则按照id的升序排列             3.主函数:     1.输入信息,并在其考场内进行排序,按照书上第1中方法确定location_number和local_rank     2.对整个结构数组排序,然后书上第2中方法,按要求输出
1.第1部分:找出s1中有但是s2中没有的,同时转化为大写字符放到字符串s中
2.第2部分:消除相同的

参考代码1:

#include<iostream>
#include<string>
using namespace std;
/*
    解题思路:
    1.第1部分:找出s1中有但是s2中没有的,同时转化为大写字符放到字符串s中
    2.第2部分:消除相同的
*/
bool HashTable[1000]={false};
int main()
{
    string s1,s2;
    string s,ans;
    getline(cin,s1);
    getline(cin,s2);
    for(int i=0; i<s2.length(); i++)
        HashTable[s2[i]]=true;
    for(int i=0; i<s1.length(); i++)
        if(HashTable[s1[i]]==false)
            s+=toupper(s1[i]);
    for(int i=0; i<s.length(); i++)
        if(ans.find(s[i])==string::npos)  //s.find('a')==string::npos 表示在字符串中s中没有找到字符a
            ans+=s[i];
    cout << ans;
    return 0;
}



知识总结:

1.判断字符串中是否含有指定的字符串

s.find('a')==string::npos //表示在字符串中s中没有找到字符a

解题思路2:

在这里插入图片描述
1.设置一个HashTale,初始值设为false
2.双层for,对于第一个字符串中每一个字符去遍历第2个字符串,当然每次都将字符改为大写字符,如果字符串
相同则退出循环,后面有if判断,如果j==str2.length()&&HashTable[c1]==false则输出且将HashTable[c1]改为true

参考代码2:

#include<iostream>
#include<string>
using namespace std;
/*
    解题思路:

    
*/
int main()
{
    string str1,str2;
    bool HashTable[128]={false};
    cin >> str1 >> str2;
    for(int i=0; i<str1.length(); i++)
    {
        int j;
        char c1,c2;
        for(j=0; j<str2.length(); j++)
        {
            c1=toupper(str1[i]);
            c2=toupper(str2[j]);
            if(c1==c2)
                break;
        }
        if(j==str2.length() && HashTable[c1]==false)
        {
            cout << c1;
            HashTable[c1]=true;
        }
    }
    return 0;
}





pat A1092


题意:

输入:

1.输入字符串s1,s2

输出:

1.如果s2中的字符都能在s1中找到,则输出yes,输出字符串长度之差
2.如果s2中有的字符不能在s1中找到或者缺少,则输出no,输出缺少个数



解题思路1:

在这里插入图片描述
1.设置一个散列表HashTable,将s1字符串中的所有字符的个数统计下来
2.从HashTable中s1字符串中-s2中字符串
3.将s2字符串消去相同的字符,保留为ans
4.以s2字符长度为基准,遍历循环HashTable,如果值<0,则flag为0(flag初值为1),最根据flag值来输出YES或者no
5.以字符串ans为准,统计出缺少字符的个数num,然后对应于yes或者no输出数值
6.如果现存的字符串中都有想要的字符串的字符,则直接输出俩个字符串长度相减,如果有缺少的,则直接输出num

参考代码1:

#include<iostream>
#include<cmath>
using namespace std;
/*
    解题思路:

*/
int HashTable[128]={0};
int main()
{
    string ans;
    int flag=1,num=0;
    string s1,s2;
    getline(cin,s1);
    getline(cin,s2);
    for(int i=0; i<s1.length(); i++)
        HashTable[s1[i]]++;
    for(int i=0; i<s2.length(); i++)
        HashTable[s2[i]]--;   //从现有的字符串中减去想要的,统计缺少的个数
    for(int i=0; i<s2.length(); i++)
        if(ans.find(s2[i])==string::npos)
            ans+=s2[i];
    for(int i=0; i<s2.length(); i++)
        if(HashTable[s2[i]]<0)
            flag=0;
    for(int i=0; i<ans.length(); i++)
    {
        if(HashTable[ans[i]]<0)
            num+=abs(HashTable[ans[i]]);
    }
    if(flag==1)
        cout << "Yes" << " " << s1.length()-s2.length();
    else
        cout << "No" << " " << num;

    return 0;
}



解题思路2:

在这里插入图片描述
1.设置散列表HashTable
2.将字符串1的字符在HashTable中统计出来
3.遍历字符串2,设置miss初值为0,用想要的字符串和现存的字符串对比相减(遇到1个减1个),然后对应的HashTable的值<0
则miss++,
4.当循环完之后,如果miss为0,表示没有缺少的,则直接输出yes,两个字符串长度相减,否则,输出no,输出miss

参考代码2:

#include<iostream>
using namespace std;
int HashTable[128]={0};
/*  
    解题思路;

*/
int main()
{
    int miss=0;
    string s1,s2;
    cin >> s1 >> s2;
    for(int i=0; i<s1.length(); i++)
        HashTable[s1[i]]++;
    for(int i=0; i<s2.length(); i++)
    {
        HashTable[s2[i]]--;
        if(HashTable[s2[i]]<0)
            miss++;
    }
    if(miss==0)
        cout << "Yes" << " " << s1.length()-s2.length();
    else
        cout << "No" << " " << miss;
    return 0;
}


pat A1041


题意:

输入:

1.输入n,后面紧接着输入n个数字


输出:

输出第1个在n个数字中只有1个的


解题思路:

在这里插入图片描述
1.设置散列HashTable
2.for循环,统计n个数字中每个数字的个数,同时将其放到数组中
3.for循环,在数组中,如果对应数字的个数为1,则输出该数字同时跳出循环,如果后面i==n,则输出NONE

参考代码:

#include<iostream>
using namespace std;
/*
    解题思路:

*/
int HashTable[10001]={0};
int main()
{
    int n,i;
    cin >> n;
    int kk[n];
    for(int i=0; i<n; i++)
    {
        int temp;
        cin >> temp;
        kk[i]=temp;
        HashTable[temp]++;
    }
    for(i=0; i<n; i++)
        if(HashTable[kk[i]]==1)
        {
            cout << kk[i];
            break;
        }
    if(i==n)
        cout << "None";
    return 0;
}




pat A1048

题意:

输入:

1.输入n,m
2.输入n个数字

输出:

最小的满足n个数字中v1+v2=m,并且v1<=v2


解题思路1:按照每个数字出现的次数作为散列

在这里插入图片描述
1.设置散列数组a,存放每个数字出现的次数
2.for循环,i从0开始循环,保证如果满足后面的要求输出最小的情况
1.a[i]>0,表示输入的数字中有该数字
2.a[i]–,(为了防止,m是输入数字的2倍这种特殊的情况,如样例2中7)
3.m>i,因为后面是a[m-i]
4.return 0
3.只有在输出不了时,最后输出NO SOlution

参考代码:

#include <iostream>
using namespace std;
int a[1001];
/*
    解题思路:

*/
int main()
{

     int n, m, temp;
     scanf("%d %d", &n, &m);
     for(int i = 0; i < n; i++)
     {
         scanf("%d", &temp);
         a[temp]++;
     }
     for(int i = 0; i < 1001; i++)
     {
         if(a[i])
         {
             a[i]--;
             if(m > i && a[m-i])
             {
                 printf("%d %d", i, m - i);
                 return 0;
             }
         }
     }
     printf("No Solution");
     return 0;
 }




解题思路2:按照输入的数字作为下标

在这里插入图片描述
1.输入数字,按照升序排列
2.以输入的数字作为下标,然后m-v[i]作为元素值
3.for循环,如果(v[i]HashTable[HashTable[v[i]]] && v[i]!=HashTable[v[i]])则输出,如果in则输出No Solution

参考代码2:

#include<iostream>
#include<algorithm>
using namespace std;
/*
    解题思路:
    1.输入数字,按照升序排列
    2.以输入的数字作为下标,然后m-v[i]作为元素值
    3.for循环,如果(v[i]==HashTable[HashTable[v[i]]] && v[i]!=HashTable[v[i]])则输出,如果i==n则输出No Solution
*/
int HashTable[10001]={501};
int main()
{
    int n,m,i,num=0;
    cin >> n >> m;
    int v[n];
    for(int i=0; i<n; i++)
        cin >> v[i];
    sort(v,v+n);
    for(int i=0; i<n; i++)
        HashTable[v[i]]=m-v[i];

    for(i=0; i<n; i++)
        if(v[i]==HashTable[HashTable[v[i]]] && v[i]!=HashTable[v[i]])
        {
            cout << v[i] << " " << m-v[i];
            break;
        }
    if(i==n)
        cout << "No Solution";
    return 0;
}


解题思路3:二分查找

在这里插入图片描述
1.将数字按照然后升序排列,i从小到大去找,j从大到小去找
2.如果和恰好是m,则直接退出程序
3.最后直接输出NO soulution

参考代码2:

#include<iostream>
#include<algorithm>
using namespace std;
/*
    解题思路:

*/
int main()
{
    int n,m,i,j;
    cin >> n >> m;
    int v[n];
    for(int i=0; i<n; i++)
        cin >> v[i];
    sort(v,v+n);
    for(i=0; i<n; i++)
        for(j=n-1; j>i; j--)
            if(v[i]+v[j]==m)
            {
                cout << v[i] << " " << v[j];
                return 0;
            }
        cout << "No Solution";
    return 0;
}


pat A1050


题意:

输入:

1.输入字符串s1,s2

输出:

1.输出s1中没有s2的字符,并且保留原来的顺序

### 解题思路:
在这里插入图片描述
1.设置散列HashTabl数组
2.输入两个字符串s1,s2
3.将s2中的所有字符进行标记
4.然后对应于字符串s1,如果字符之前被标记过则不输出,否则输出

参考代码:

#include<iostream>
using namespace std;
bool HashTable[10001]={false};
/*
    解题思路:

*/
int main()
{
    string s1,s2;
    getline(cin,s1);
    getline(cin,s2);
    for(int i=0; i<s2.length(); i++)
        HashTable[s2[i]]=true;
    for(int i=0; i<s1.length(); i++)
        if(HashTable[s1[i]]==false)
            cout << s1[i];
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值