网上看到一道腾讯关于字符串匹配的面试题,欢迎大家讨论!

HelloWorldGone 2012-09-08 09:26:18
加精
假设两个字符串中所含有的字符和个数都相同我们就叫这两个字符串匹配,
比如:abcda和adabc,由于出现的字符个数都是相同,只是顺序不同,
所以这两个字符串是匹配的。要求高效!
...全文
21607 355 打赏 收藏 转发到动态 举报
写回复
用AI写文章
355 条回复
切换为时间正序
请发表友善的回复…
发表回复
商科程序员 2015-03-12
  • 打赏
  • 举报
回复
可以用著名的素数相乘算法
zhouxiaofeng1021 2015-03-12
  • 打赏
  • 举报
回复
编程珠玑里面就采用了HASH 如果可以预处理,则O(1)吧
liangtu 2015-03-06
  • 打赏
  • 举报
回复
越想越觉得有意思,性能不好控制。
  • 打赏
  • 举报
回复
引用 6 楼 nice_cxf 的回复:
假定n为字符串长度 方法1:先排序然后比较,复杂度是o(n*log(n)),如果只是一次比较,这个效率低,如果重复多次比较,可以考虑 方法2:建立两个52个int的数组(假定字符串只包含字母,如果不是的话,设为127或255(看是否包括中文)),然后分别遍历字符串,记录每个字符串中每个字母的个数,最后对两个数组进行内存比较查看是否相等复杂度为o(n)
哈希的实现没有方法2快
daylesslu 2015-03-02
  • 打赏
  • 举报
回复
其实每次从str1,str2中读取比较之后根据count的正负,改变不同字符串的个数,虽好情况下2logn 就可以判断是否一样,最差的是2n,这个比稳定的2n稍微好一些。换句话是说count个不同需要读取count个字符消减得到0,结束标志是count大于剩下的字符数。
znhehandong 2014-12-29
  • 打赏
  • 举报
回复
把两个字符串看成是字符流就好,每次取8bit 作异或计算,如果两个字符串是相同的,最后肯定最终结果为0,不同的则不为0. 例子: a 二进制 为 1100001 b二进制为 1100010 子串ab 和 ba 。 结果就是 0 ^1100001^1100010^1100010^1100001 = 0. 主要是依据 相同的两个字符异或肯定为0 这么做还可以忽略字符编码的问题,因为只要编码是相同的,对于同一个字符其二进制肯定是一样的。。 复杂度O(n)
code-artist 2014-11-24
  • 打赏
  • 举报
回复
将快排稍微改进一下,同时对两个字符串进行排序,这样应该更快些。
cnmhx 2014-11-11
  • 打赏
  • 举报
回复
我有个新方案,值发帖者给200分吧! 将字母(譬如26个)按照顺序统计字符串中的出现次数构成一个数字串。 例如帖子中的字符串“adcda”, 201200000... 比较俩数字串是否相等就等价于字符串匹配问题。 当字符串很长时,这种方法很高效。
Wood_69 2014-11-09
  • 打赏
  • 举报
回复
引用 346 楼 u010787773 的回复:
使用C++ 的MAP或者简单点自己写hash,然后遍历看2个hash是否相同,不知道有没有效率更高的。
算是个“热度”排序问题,加上比较问题 对于大数据来说应该是要用hash吧
cjmcp 2014-08-08
  • 打赏
  • 举报
回复
使用C++ 的MAP或者简单点自己写hash,然后遍历看2个hash是否相同,不知道有没有效率更高的。
zy_think123 2014-08-02
  • 打赏
  • 举报
回复
先排序,然后比较 第一个字符数组从两端开始扫描,然后和第二个字符数组的第一个字符开始比较,只要有一个不同,就证明不一样 过于笨拙了
top_worker 2014-07-18
  • 打赏
  • 举报
回复
引用 193 楼 pupingpp 的回复:
转自v_JULY_v的博客:
//copyright@ nossiac  
//July、updated,2011.04.24。  
#include <stdio.h>  
#include <string.h>  
  
#define getbit(x) (1<<(x-'a'))  
  
void a_has_b(char * a, char * b)  
{  
    int i = 0;  
    int dictionary = 0;  
    int alen = strlen(a);  
    int blen = strlen(b);  
      
    for(i=0;i<alen;i++)  
        dictionary |= getbit(a[i]);  
      
    for(i=0;i<blen;i++)  
    {  
        if(dictionary != (dictionary|getbit(b[i])))  
            break;  
    }  
      
    if(i==blen)  
        printf("YES! A has B!/n");  
    else  
        printf("NiO!  Char at %d is not found in dictionary!/n",i);  
}  
  
int main()  
{  
    char * str1="abcdefghijklmnopqrstuvwxyz";  
    char * str2="akjsdfasdfiasdflasdfjklffhasdfasdfjklasdfjkasdf";  
    char * str3="asdffaxcfsf";  
    char * str4="asdfai";  
      
    a_has_b(str1, str2);  
    a_has_b(str1, str3);  
    a_has_b(str3, str4);  
      
    return 0;  
}  
个人觉得还可以用异或来实现的,哈哈,不过思想都差不多,就不贴代码了
运行的结果显示 for(i=0;i<alen;i++) dictionary |= getbit(a[i]); 实现加法并将结果赋值给dictionary 而 if(dictionary != (dictionary|getbit(b[i]))) break; 这边为什么dictionary|getbit(b[i])不是相加,而且判断是否包含呢“看不懂 运行程序如下 for(i=0;i<alen;i++) { qDebug()<<"---00--a="<<getbit(a[i]); qDebug()<<"---00--i="<<i<<"--"<<dictionary; dictionary |= getbit(a[i]); qDebug()<<"---00--i="<<i<<"--"<<dictionary; } for(i=0;i<blen;i++) { qDebug()<<"---11--b="<<getbit(b[i]); qDebug()<<"---11--i="<<i<<"--"<<dictionary; qDebug()<<"---11-2-i="<<i<<"--"<<(dictionary|getbit(b[i])); if(dictionary != (dictionary|getbit(b[i]))) break; } 运行结果: ---00--a= 1 ---00--i= 0 -- 0 ---00--i= 0 -- 1 ---00--a= 262144 ---00--i= 1 -- 1 ---00--i= 1 -- 262145 ---00--a= 8 ---00--i= 2 -- 262145 ---00--i= 2 -- 262153 ---00--a= 32 ---00--i= 3 -- 262153 ---00--i= 3 -- 262185 ---00--a= 32 ---00--i= 4 -- 262185 ---00--i= 4 -- 262185 ---00--a= 1 ---00--i= 5 -- 262185 ---00--i= 5 -- 262185 ---00--a= 8388608 ---00--i= 6 -- 262185 ---00--i= 6 -- 8650793 ---00--a= 4 ---00--i= 7 -- 8650793 ---00--i= 7 -- 8650797 ---00--a= 32 ---00--i= 8 -- 8650797 ---00--i= 8 -- 8650797 ---00--a= 262144 ---00--i= 9 -- 8650797 ---00--i= 9 -- 8650797 ---00--a= 32 ---00--i= 10 -- 8650797 ---00--i= 10 -- 8650797 ---11--b= 1 ---11--i= 0 -- 8650797 ---11-2-i= 0 -- 8650797 ---11--b= 262144 ---11--i= 1 -- 8650797 ---11-2-i= 1 -- 8650797 ---11--b= 8 ---11--i= 2 -- 8650797 ---11-2-i= 2 -- 8650797 ---11--b= 32 ---11--i= 3 -- 8650797 ---11-2-i= 3 -- 8650797 ---11--b= 1 ---11--i= 4 -- 8650797 ---11-2-i= 4 -- 8650797 ---11--b= 256 ---11--i= 5 -- 8650797 ---11-2-i= 5 -- 8651053 ---22--i= 5 --blen= 6
top_worker 2014-07-18
  • 打赏
  • 举报
回复
引用 221 楼 meiyuli 的回复:
#include <IOSTREAM>
using namespace std;

int main()
{
	char s1[256];
	char s2[256];
	cin >> s1;
	cin >> s2;
	int lenth;
	if ((lenth = strlen(s1)) == strlen(s2))
	{
		unsigned char check = 0;
		for (int i = 0; i < lenth; i++)
		{
			check ^= s1[i];
			check ^= s2[i];
		}
		if (check)
		{
			cout << "不匹配" << endl;
		}else
		{
			cout << "匹配" << endl;
		}
	}else
	{
		cout << "不匹配" << endl;
	}
	return 0;
}
如果s1 =“aa”,s2 =“bb”;输出的结果是不是:匹配啊?
ProjectDD 2014-04-12
  • 打赏
  • 举报
回复
引用 340 楼 libralibra 的回复:
[quote=引用 328 楼 ganmaojiushijiu 的回复:] [quote=引用 1 楼 Jia_H 的回复:] 假定字符串中都是ASCII字符。如下用一个数组来计数,前者加,后者减,全部为0则匹配。

        static bool IsMatch(string s1, string s2)
        {
            if (s1 == null && s2 == null) return true;
            if (s1 == null || s2 == null) return false;

            if (s1.Length != s2.Length) return false;

            int[] check = new int[128];

            foreach (char c in s1)
            {
                check[(int)c]++;
            }
            foreach (char c in s2)
            {
                check[(int)c]--;
            }
            foreach (int i in check)
            {
                if (i != 0) return false;
            }

            return true;
        }
这个根本就没用如果是 ac bb这两个字符串呢?[/quote] 你看懂1楼的算法了吗?[/quote] 你确定实验过? 这个代码我从思想到算法都没有什么问题,而且我检验过,真实有效,check[a],check[c] 上有1和check[b]有两个1本来就不是一样
wariolsb 2014-04-11
  • 打赏
  • 举报
回复
引用 6 楼 nice_cxf 的回复:
假定n为字符串长度 方法1:先排序然后比较,复杂度是o(n*log(n)),如果只是一次比较,这个效率低,如果重复多次比较,可以考虑 方法2:建立两个52个int的数组(假定字符串只包含字母,如果不是的话,设为127或255(看是否包括中文)),然后分别遍历字符串,记录每个字符串中每个字母的个数,最后对两个数组进行内存比较查看是否相等复杂度为o(n)
libralibra 2014-04-04
  • 打赏
  • 举报
回复
引用 328 楼 ganmaojiushijiu 的回复:
[quote=引用 1 楼 Jia_H 的回复:] 假定字符串中都是ASCII字符。如下用一个数组来计数,前者加,后者减,全部为0则匹配。

        static bool IsMatch(string s1, string s2)
        {
            if (s1 == null && s2 == null) return true;
            if (s1 == null || s2 == null) return false;

            if (s1.Length != s2.Length) return false;

            int[] check = new int[128];

            foreach (char c in s1)
            {
                check[(int)c]++;
            }
            foreach (char c in s2)
            {
                check[(int)c]--;
            }
            foreach (int i in check)
            {
                if (i != 0) return false;
            }

            return true;
        }
这个根本就没用如果是 ac bb这两个字符串呢?[/quote] 你看懂1楼的算法了吗?
jay007333 2014-04-04
  • 打赏
  • 举报
回复
转为字符串数组,在单个取hashCode值累计,最后比较两数组累计值是否相同 // TODO Auto-generated method stub String a = "abcda"; String b = "adabc"; int s=0; int c=0; char[] ch = a.toCharArray(); char[] ch1 = b.toCharArray(); if(ch.length==ch1.length) { for(int i=0;i<ch.length;i++) { s+=String.valueOf(ch[i]).hashCode(); c+=String.valueOf(ch1[i]).hashCode(); } if((s-c)==0) { System.out.println("两个字符串匹配"); }else { System.out.println("两个字符串不匹配"); } }else { System.out.println("两个字符串不匹配"); }
L_O_C 2014-04-01
  • 打赏
  • 举报
回复

public static bool Match(char[] arr1, char[] arr2) {
    if (arr1.Length != arr2.Length) {
        return false;
    }

    int offset = 0;
    int x = 0;
    for (int i = 0; i < arr1.Length; ++i) {
        offset += (int)arr1[i];
        offset -= (int)arr2[i];
        x ^= arr1[i] ^ arr2[i];
    }

    return offset == 0 && x == 0;
}
ProjectDD 2014-03-28
  • 打赏
  • 举报
回复
        public static bool CheckMatch(this string s1, string s2) {
            if (s1 == null || s2 == null) return false;
            if (s1.Length != s2.Length) return false;
            int[] check = new int[128];
            var len = s1.Length;
            foreach (var c in s1) {
                check[c]++;
            }
            foreach (var c in s2) {
                check[c]--;
            }
            return check.Max() == 0 && check.Min() == 0;
        }
sjhcsdn 2014-03-28
  • 打赏
  • 举报
回复
public static bool CheckMatch(this string s1, string s2) { if (s1 == null || s2 == null) return false; if (s1.Length != s2.Length) return false; int[] check = new int[128]; foreach (char c in s1) { check[c]++; } foreach (char c in s2) { check[c]--; } return !(check.Max()!=0); } // 修改以后的样子,通过测试 ok
加载更多回复(313)

33,010

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧