字符串数组的去重

本文介绍了一种在处理大量字符串输入时,通过调整cin设置来避免超时的方法。原本的代码在在线评测系统中遇到超时问题,通过取消cin与stdin的同步,显著提高了输入效率,解决了超时问题。

字符串数组的去重

输入

第一行为个数n,之后n行每行一个字符串(1<n<50000)

输出

输出不重复的字符串的个数

输入样例

3
aaaa
AAAa
aaaa

输出样例

2

 我一开始是这样写的,结果在oj提交的时候第三个测试用例超时了。

#include <bits/stdc++.h>
using namespace std;
int main()
{
    map<string,int> Map;        
    int n;
    cin >> n;
    string s[n];   
    // 输入n行字符
    for(int i=0;i<n;i++)
    {
        cin >> s[i];
    }
    int Count = 0;
    for(string word:s)  
    //for-each循环,将字符串数组s中的每个字符串依次取出,赋值给word
    {
        if(Map[word]==0)
        {
            Count++;   //统计字符串数组中不同字符串的数目
        }
        Map[word] = 1;  
        /*这里没有使用Map[word]++;
         *因为我们只需要知道这个字符出现过就行了,
         *并不需要记录每个字符串出现的次数,所以直接赋值为1
         */
    }
    cout << Count;
    return 0;
}

于是,在仔细分析代码之后,我觉得是cin造成了我的代码超时,然后我百度了一下解决cin造成超时的方法。

AC代码如下:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios::sync_with_stdio(false); //取消cin和stdin的同步
    map<string,int> Map;        
    int n;
    cin >> n;
    string s[n];   
    // 输入n行字符
    for(int i=0;i<n;i++)
    {
        cin >> s[i];
    }
    int Count = 0;
    for(string word:s)  
    //for-each循环,将字符串数组s中的每个字符串依次取出,赋值给word
    {
        if(Map[word]==0)
        {
            Count++;   //统计字符串数组中不同字符串的数目
        }
        Map[word] = 1;  
        /*这里没有使用Map[word]++;
         *因为我们只需要知道这个字符出现过就行了,
         *并不需要记录每个字符串出现的次数,所以直接赋值为1
         */
    }
    cout << Count;
    return 0;
}

 

<think>嗯,用户想用JavaScript对字符串数组。我需要先回忆一下常见的方法。首先,最简单的可能是用Set,因为Set自动。例如,[...new Set(array)]就可以。不过用户的是字符串数组,所以这个方法应该适用。但要注意的是,Set是基于严格相等性,所以像"5"和5不会被视为复,但如果是字符串数组的话,不会有这个问题。然后,用户可能希望看到其他方法,比如使用filter和indexOf的方法。比如array.filter((item,index)=> array.indexOf(item) ===index)。这种方法在旧版浏览器中可能兼容性更好,但时间复杂度是O(n²),对于大数组可能效率不高。还有引用中提到的使用对象来记录是否复的方法,比如用对象来存储已经出现过的字符串,这样检查是否存在的时间是O(1),整体时间复杂度是O(n)。不过对于字符串数组来说,这种方法需要注意属性名的唯一性,比如用字符串作为键,这样不会有类型转换的问题。比如引用的第二个方法,把不同类型分开存储,但对于纯字符串数组可能不需要这么复杂,直接用对象或者Set就行。 另外,用户提到的第三个引用中的indexOf方法,但那个方法可能效率低,特别是数组很大的时候。不过对于字符串数组来说,如果数组不是特别大,这种方法可能足够用。还要考虑是否保持原数组的顺序。Set和filter/indexOf的方法都会保持顺序,而使用对象的方法如果正确实现的话也能保持顺序。比如在遍历数组时,第一次出现的元素保留,后面复的掉。 然后,用户可能需要具体的代码示例。比如,使用Set的最简单方式: constuniqueArray= [...new Set(originalArray)];或者使用reduce: constuniqueArray= originalArray.reduce((acc, current) =>{if (!acc.includes(current)){acc.push(current);}returnacc;}, []); 不过这种方法也是O(n²)的时间复杂度。 还有更高效的方法,比如使用对象来记录已出现的元素:functionremoveDuplicates(arr) {constseen ={};return arr.filter(item=> {returnseen.hasOwnProperty(item)? false: (seen[item]= true);}); }这种方法对于字符串数组来说,需要注意如果字符串可能包含像"toString"这样的属性名,可能会有冲突,不过这种情况比较少见。或者可以使用Map来避免这个问题,因为Map的键可以是任意值,而对象的键只能是字符串或Symbol。不过对于纯字符串数组来说,使用对象应该没问题,因为字符串作为键不会有冲突,除非数组中有相同的字符串,但复的字符串本来就是要的。所以综合起来,最简洁高效的方法是使用Set,其次是使用对象或Map的方法。需要根据用户的需求选择,如果用户需要兼容性更好的方法,可能需要用filter/indexOf或者对象的方法,如果用户使用ES6环境,推荐Set。另外,用户的问题是关于字符串数组的,所以不需要处理对象或不同类型的元素,可以简化代码。比如引用中的第二个方法处理了不同类型的元素,但用户的情况可能不需要,可以调整代码。 最后,需要给出代码示例,并比较不同方法的优缺点,比如时间复杂度、兼容性、是否保持顺序等。这样用户可以根据自己的情况选择合适的方法。</think>### JavaScript字符串数组方法 #### 方法一:使用Set对象(ES6+) 利用Set自动过滤复值的特性,转换为数组后即可得到唯一结果。这是最高效简洁的方法,时间复杂度$O(n)$。 ```javascript const names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"]; const uniqueNames = [...new Set(names)]; console.log(uniqueNames); // ["Mike","Matt","Nancy","Adam","Jenny","Carl"] ``` #### 方法二:使用对象哈希(ES5兼容) 通过对象属性快速判断复元素,时间复杂度$O(n)$[^2]。 ```javascript function removeDuplicates(arr) { const seen = {}; return arr.filter(item => seen.hasOwnProperty(item) ? false : (seen[item] = true) ); } ``` #### 方法三:使用filter+indexOf 通过遍历时检查首次出现位置,时间复杂度$O(n^2)$,适合小数组[^3]。 ```javascript const uniqueNames = names.filter((item, index) => names.indexOf(item) === index ); ``` #### 方法四:使用reduce 通过累加器逐步构建唯一数组,时间复杂度$O(n^2)$。 ```javascript const uniqueNames = names.reduce((acc, cur) => acc.includes(cur) ? acc : [...acc, cur], [] ); ``` #### 性能对比 | 方法 | 时间复杂度 | 兼容性 | 保持顺序 | |------------|--------|------|------| | Set | O(n) | ES6+ | 是 | | 对象哈希 | O(n) | ES5+ | 是 | | filter+indexOf | O(n²) | ES5+ | 是 | | reduce | O(n²) | ES5+ | 是 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喜欢ctrl的cxk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值