for(char&c:s)和for(char c:s)之间的区别?

edj*_*ker 1 c++

这是leetcode上的问题

给定仅包含字符'(',')','{','}','['和']'的字符串,请确定输入字符串是否有效。

括号必须以正确的顺序闭合,“()”和“()[] {}”都是有效的,而“(]”和“([]]”则无效。

这是一个解决方案:

class Solution {
public:
    bool isValid(string s) {
        stack<char> paren;
        for (char& c : s) {
            switch (c) {
                case '(': 
                case '{': 
                case '[': paren.push(c); break;
                case ')': if (paren.empty() || paren.top()!='(') return false; else paren.pop(); break;
                case '}': if (paren.empty() || paren.top()!='{') return false; else paren.pop(); break;
                case ']': if (paren.empty() || paren.top()!='[') return false; else paren.pop(); break;
                default: ; // pass
            }
        }
        return paren.empty() ;
    }
};
Run Code Online (Sandbox Code Playgroud)

这是另一个解决方案:

class Solution {
public:
    bool isValid(string s) {
        stack<char> paren;
        for (char c : s) {
            switch (c) {
                case '(': 
                case '{': 
                case '[': paren.push(c); break;
                case ')': if (paren.empty() || paren.top()!='(') return false; else paren.pop(); break;
                case '}': if (paren.empty() || paren.top()!='{') return false; else paren.pop(); break;
                case ']': if (paren.empty() || paren.top()!='[') return false; else paren.pop(); break;
                default: ; // pass
            }
        }
        return paren.empty() ;
    }
};
Run Code Online (Sandbox Code Playgroud)

两种解决方案之间的唯一区别是

for (char& c : s) 
Run Code Online (Sandbox Code Playgroud)

在第一个解决方案中

for (char c : s) 
Run Code Online (Sandbox Code Playgroud)

在第二个解决方案中。但是,第一个解决方案仅花费3毫秒,第二个解决方案仅花费6毫秒。那么,为什么第一个解决方案要比第二个解决方案快?

Arn*_*rah 5

for (char c : s) 
Run Code Online (Sandbox Code Playgroud)

这会在中创建每个元素的副本s并将其存储在中c。这意味着修改c不会修改s

for (char& c : s) 
Run Code Online (Sandbox Code Playgroud)

但这不是在创建每个元素的副本s直接,而是在参考文献,并将其存储c作为别名。这意味着修改c 确实会修改s

由于复制可能是一项昂贵的操作,因此复制的性能要比引用慢(即使在不存在优化的情况下使用内置类型),这也避免了复制。

如果要防止在不知不觉中修改字符串,则可以使用const引用,即:

for (const char& c : s) 
Run Code Online (Sandbox Code Playgroud)

  • “相对于引用,它的性能要慢”,这并不总是正确的,尤其是对于内置类型。 (3认同)