c++ 当我的代码在VisualStudio上显示正确的输出时,Leetcode给了我一个错误的答案[关闭]

qqrboqgw  于 2024-01-09  发布在  其他
关注(0)|答案(1)|浏览(148)

**已关闭。**此问题需要debugging details。目前不接受回答。

编辑问题以包括desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem。这将帮助其他人回答问题。
2天前关闭。
Improve this question
我正在做“1662.检查两个字符串数组是否等价”。
我在VisualStudio上编写的解决方案代码给出了正确的输出,即false,但是当我在Leetcode上键入相同的代码时,它说它给出了输出true,我不知道为什么它应该给出false输出

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. int main() {
  5. string word1[] = { "a","cb" }, word2[] = { "ab","c" };
  6. string com1 = "", com2 = "";
  7. int size1 = sizeof(word1) / sizeof(word1[0]), size2 = sizeof(word2) / sizeof(word2[0]);
  8. for (int i = 0; i < size1; i++) {
  9. com1 += word1[i];
  10. }
  11. for (int i = 0; i < size2; i++) {
  12. com2 += word2[i];
  13. }
  14. if (com1 == com2) {
  15. cout << "true";
  16. }
  17. else {
  18. cout << "false";
  19. }
  20. return 0;
  21. }

字符串

mctunoxg

mctunoxg1#

这个帖子里有一些东西是给每个人的。
Maven级的C++程序员会发现@Marek R发布的优雅解决方案是一种乐趣。他使用范围库来生成一行解决方案:
正确的解决方案,它不会在LeetCode(旧的标准库). godbolt.org/z/a3GK7b7GT上编译。

  1. // Solution by @Marek R
  2. bool arrayStringsAreEqual(std::vector<std::string>& word1, std::vector<std::string>& word2)
  3. {
  4. return std::ranges::equal(std::ranges::join_view(word1), std::ranges::join_view(word2));
  5. }

字符串
对于初学者来说,OP中使用的算法并不可耻。他只是简单地连接组成一个单词的所有字符串,然后比较结果。毫无疑问,这是非常低效的,但它确实有效。如果你是一个C++新手,这是一个可以接受的解决方案。
然而,当LeetCode提交这样的解决方案时,可能会出现问题。我怀疑LeetCode会在测试中使用一些相当长的字符串。这可能会导致运行时不佳,内存占用率高。
对于中级程序员,我们有@Jarod42给出的提示:
顺便说一句,你不需要创建大字符串...
技巧是对每个单词向量进行一次遍历,并跟踪接下来要比较的字符串和字符的位置。我为此编写了一个夸张的版本,其中包括一个迭代器类来跟踪位置。(见下文)
OP的问题
当我在Leetcode上输入相同的代码时...[它给出了不正确的输出]。
这是因为std::vector(LeetCode解决方案使用)和内置数组(函数main使用)的不兼容性。您不能简单地 * 键入相同的代码。* 您必须修改函数main中的代码,使其使用std::vector
@PaulMcKenzie概述了在Visual Studio中解决LeetCode问题的最佳方法。您必须从LeetCode网站复制类Solution,并编写函数main以与之接口。
下面是我在我的解决方案中使用的框架。注意,它从LeetCode网站复制了Solution * 类。

  1. // main.cpp
  2. #include <algorithm>
  3. #include <iostream>
  4. #include <sstream>
  5. #include <string>
  6. #include <string_view>
  7. #include <type_traits>
  8. #include <vector>
  9. // These using declarations allows the LeetCode Solution
  10. // to be used without modifying its function signature.
  11. using std::string;
  12. using std::vector;
  13. class Solution {
  14. public:
  15. bool arrayStringsAreEqual(vector<string>& word1, vector<string>& word2) {
  16. return {};
  17. }
  18. };
  19. std::ostream& operator<< (std::ostream& ost, std::vector<std::string> const& v)
  20. {
  21. ost.put('[');
  22. if (!v.empty())
  23. for (auto it{ v.cbegin() };;)
  24. {
  25. ost << std::quoted(*it);
  26. if (++it == v.cend())
  27. break;
  28. ost.put(',');
  29. }
  30. ost.put(']');
  31. return ost;
  32. }
  33. void solve(
  34. std::string_view heading,
  35. std::vector<std::string> word1,
  36. std::vector<std::string> word2)
  37. {
  38. std::cout
  39. << std::boolalpha
  40. << heading
  41. << "\n"
  42. << "\n Input: word1 = " << word1 << ", word2 = " << word2
  43. << "\n Output: " << Solution{}.arrayStringsAreEqual(word1, word2)
  44. << "\n\n";
  45. }
  46. int main()
  47. {
  48. std::cout << "LeetCode 1662. Check If Two String Arrays are Equivalent"
  49. "\nhttps://leetcode.com/problems/check-if-two-string-arrays-are-equivalent/"
  50. "\n\n";
  51. using namespace std::string_literals;
  52. solve("Example 1", { "ab"s, "c"s }, { "a"s, "bc"s });
  53. solve("Example 2", { "a"s, "cb"s }, { "ab"s, "c"s });
  54. solve("Example 3", { "abc"s, "d"s, "defg"s }, { "abcddefg"s });
  55. return 0;
  56. }
  57. // end file: main.cpp


Solution只是一个存根,但是,这个程序运行,并为所有三个例子产生答案false

  1. LeetCode 1662. Check If Two String Arrays are Equivalent
  2. https://leetcode.com/problems/check-if-two-string-arrays-are-equivalent/
  3. Example 1
  4. Input: word1 = ["ab","c"], word2 = ["a","bc"]
  5. Output: false
  6. Example 2
  7. Input: word1 = ["a","cb"], word2 = ["ab","c"]
  8. Output: false
  9. Example 3
  10. Input: word1 = ["abc","d","defg"], word2 = ["abcddefg"]
  11. Output: false


在上面的框架中,我没有完成类Solution。这是故意的。我希望OP能找出如何在这个框架中编写他的算法。

使用迭代器跟踪字符串和字符位置

本节介绍了另一种解决方案,即使用迭代器来扫描“单词”。
这种方法的优点是operator==代码的简单性,它实际上与您可能编写的比较两个字符串的代码相同。

  1. bool operator==(Word const& that) const {
  2. if (this->length() != that.length())
  3. return false;
  4. auto i1{ this->cbegin() }; // iterator into `this` word
  5. auto i2{ that.cbegin() }; // iterator into `that` word
  6. while (i1 != this->cend()) // iterator has `operator==`
  7. if (*i1++ != *i2++) // iterator has `operator*` and `operator++`
  8. return false;
  9. return true;
  10. }


通过调用标准库函数std::equal来比较单个字符,您可以做得更好。

  1. bool operator==(Word const& that) const {
  2. return this->length() == that.length()
  3. && std::equal(this->cbegin(), this->cend(), that.cbegin());
  4. }


下面是Word类的其余部分。它嵌套在Solution类中。成员函数cbegincend分别返回迭代器到Word的开头和结尾。成员函数length调用标准库函数std::accumulate来计算Word中所有字符串长度的总和。

  1. class Solution
  2. {
  3. class Word
  4. {
  5. public:
  6. struct Const_Iterator
  7. {
  8. // ...
  9. };
  10. private:
  11. std::vector<std::string> const& word;
  12. public:
  13. explicit Word(std::vector<std::string> const& word)
  14. : word{ word }
  15. {}
  16. Const_Iterator cbegin() const {
  17. return Const_Iterator(word);
  18. }
  19. Const_Iterator cend() const {
  20. Const_Iterator it(word);
  21. it.w = word.size();
  22. it.c = {};
  23. return it;
  24. }
  25. std::size_t length() const {
  26. return std::accumulate(word.cbegin(), word.cend(), std::size_t{},
  27. [](std::size_t const acc, std::string const& s)
  28. { return acc + s.length(); }
  29. );
  30. }
  31. bool operator==(Word const& that) const {
  32. return this->length() == that.length()
  33. && std::equal(this->cbegin(), this->cend(), that.cbegin());
  34. }
  35. };
  36. public:
  37. bool arrayStringsAreEqual(vector<string>& word1, vector<string>& word2) {
  38. return Word{ word1 } == Word{ word2 };
  39. }
  40. };


在类Solution中,注意函数arrayStringsAreEqual的简单性。它构造了两个临时Word对象,然后使用类Word中的operator==对它们进行比较。
最后,下面是struct Const_Iterator的代码。

  1. struct Const_Iterator
  2. {
  3. using iterator_category = std::forward_iterator_tag;
  4. using value_type = const char;
  5. using difference_type = std::ptrdiff_t;
  6. using pointer = value_type*;
  7. using reference = value_type&;
  8. std::vector<std::string> const& word;
  9. std::size_t w{}; // subscript into vector `word`, keys current word
  10. std::size_t c{}; // subscript into current word; keys next character
  11. explicit Const_Iterator(std::vector<std::string> const& word)
  12. : word{ word }
  13. {}
  14. char const& operator*() const {
  15. return word.at(w).at(c);
  16. }
  17. bool at_end() const {
  18. return w == word.size();
  19. }
  20. Const_Iterator& operator++() {
  21. if (at_end())
  22. throw std::runtime_error("Iterator out of range.");
  23. if (++c >= word.at(w).length()) {
  24. ++w;
  25. c = {};
  26. }
  27. return *this;
  28. }
  29. Const_Iterator operator++(int) {
  30. Const_Iterator tmp{ *this };
  31. ++(*this);
  32. return tmp;
  33. }
  34. bool operator==(Const_Iterator const& that) const {
  35. return &this->word == &that.word
  36. && this->w == that.w
  37. && this->c == that.c;
  38. }
  39. };

展开查看全部

相关问题