【问题标题】:Finding the largest three-digits number "within" a number查找数字“内”的最大三位数
【发布时间】:2021-06-03 21:25:59
【问题描述】:

对于这个问题,我需要在一个较大的数字中找到最大的三位数字。

示例测试用例 1:
534535
输出:
535


示例测试用例 2:
23457888976
输出:
976

我试过以下代码:
        #include <iostream>
        using namespace std;
        int main() {
        int num;
        cin>>num;
        int len= to_string(num).length();
        int arr[10],lnum=0,max=0;
        for (int i =len-1;i>=0;i--)
        {
        arr[i] = num%10;
        num =num/10;    //to convert int into array
        }
        for (int i=0;i<len-2;i++)
        {
        if (arr[i] >arr[i+1])
            lnum = arr[i]*100+arr[i+1]*10+arr[i];
        if (lnum>max)
            max= lnum;  
        }
        cout<<max;
        return 0;
    }

尽管此代码似乎适用于测试用例 1,但它不适用于大多数输入。

(也请帮忙。)
1. 这仅适用于 10 位数字(同样,大多数输出​​错误)。如果数字较大怎么办?
2.有没有更好的方法将整数转换成数组?或者字符串数组会以类似的方式工作吗?
3.真的很慢,谁能帮我弄清楚如何加快速度?
谢谢你的帮助 !!

【问题讨论】:

  • 将它们分析为字符串而不是数字。它更简单,产生错误的可能性更小
  • 使用滑动窗口算法
  • 提示:n % 1000 提取n 的最右边三位数字。 n /= 10 删除 n 的最后一位数字。不要忘记考虑否定n 的情况。你的测试用例是邪恶的——两个最大的数字都在最后。多做一些测试。另一个注意事项:考虑到无论如何您都是从标准输入加载,使用字符串方法可能不是一个坏主意。
  • @IWonderWhatThisAPIDoes thnx,你能帮我写代码吗?
  • 当然,你在哪里卡住了? ;)

标签: c++ algorithm search


【解决方案1】:

Python3 中的解决方案

#!/usr/bin/env python

num = input("Enter the number : ")

if len(num) == 3:
    print(f"Largest digit is : {num}")
    exit(0)
elif len(num) < 3:
    print(-1)
    exit(0)

maxans = int((num[0].replace("0", "")))*100 + int((num[1].replace("0", "")))*10 + int((num[2].replace("0", "")))
prev = maxans

for i in range(3, 6):
    cur = (prev%100)*10 + int((num[i].replace("0", "")))
    maxans = max(maxans, cur)
    prev = cur

print(f"The Largest num = : {maxans}")

【讨论】:

    【解决方案2】:

    这种方法适用于您可以存储在变量中的任何大数字。方法如下,

    首先将数字转换为字符串,然后创建一个包含所有可能的 3 位数字的数组,如下所示,

    号码 = 534535
    所有可能的 3 位数字数组 = ["534", "345", "453", "535"]

    然后对这个数组进行排序,排序后最后一个元素将是最大三位数,如下所示,
    排序数组 = ["345", "453", "534", "535"]

    另一个例子,
    号码 = 23457888976
    所有可能的 3 位数字数组 = ["234", "345", "457", "578", "788", "888", "889", "897", "976"]
    排序后,最后一个元素是最大数量,如下所示
    排序数组 = ["234", "345", "457", "578", "788", "888", "889", "897", "976"]

    注意Radix sort 的性能将优于 std::sort()std::sort() 提供 Quick sort。基数排序是字符串排序的理想选择,特别是在这种情况下,因为最大存储桶大小仅为 10(可能范围为 0-9),但您必须自己实现 radix sort

    #include <iostream>
    
    #include <vector>
    #include <string>
    #include <algorithm>
    
    using std::cout;
    
    std::vector<std::string> allThreeDigitNumbers(const std::string& numStr){
    
        std::vector<std::string> allNumStr(numStr.size() - 2, std::string("000"));
        std::vector<std::string>::iterator aIt = allNumStr.begin();
    
        for(std::string::const_iterator it = numStr.cbegin(), lastIt = it + (numStr.size() - 2); lastIt != it; ++it, ++aIt){
    
            std::copy(it, it + 3, aIt->begin());
        }
    
        return allNumStr;
    }
    
    unsigned maxThreeDigitNumberInNumber(unsigned long long num){
    
        std::string numStr = std::to_string(num);
    
        if(numStr.size() < 3){
    
            return 0;
        }
    
        std::vector<std::string> allNumStr = allThreeDigitNumbers(numStr);
    
        std::sort(allNumStr.begin(), allNumStr.end());
    
        return std::stoul(allNumStr.back());
    }
    
    int main(){
        cout<< "Max 3 digits number of 534535 => "<< maxThreeDigitNumberInNumber(534535)<< '\n';
        cout<< "max 3 digits number of 23457888976 => "<< maxThreeDigitNumberInNumber(23457888976)<< '\n';
    }
    

    输出

    Max 3 digits number of 534535 => 535
    max 3 digits number of 23457888976 => 976
    

    【讨论】:

      【解决方案3】:
      #include <iostream>
      #include <string>
      using namespace std;
      int main() {
          int i, n;
          string s;
          cin >> s;
          n = (int)s.size();
          if(n<3){
              /* there are less than 3 digits in the input number
              Here, you can print the number itself as it will be largest number or
              print -1 which can state that no 3 digit number exists.
              */
              cout<<-1;
              return 0;
          }
          int maxans = (s[0]-'0')*100 + (s[1]-'0')*10 + (s[2]-'0');
          // storing the first 3 digits as the maximum answer till now.
          int prev = maxans;
          for(i = 3;i<n;i++){
              int cur = (prev%100)*10 + (s[i]-'0'); // using %100 to extract the last two digits and then multiplying by 10 and adding the ith digit to make the next 3 digit number.
              maxans = max(maxans, cur);
              prev = cur;
          }
          cout<<maxans;
          return 0;
      }
      

      这段代码的时间复杂度为 O(n),其中 n 是输入字符串的长度,空间复杂度为 O(1)

      【讨论】:

        【解决方案4】:

        阅读 cmets 了解以下代码:

        #include <assert.h>
        #include <iostream>
        #include <boost/hana/functional/partial.hpp>
        #include <functional>
        #include <range/v3/to_container.hpp>
        #include <range/v3/view/all.hpp>
        #include <range/v3/view/drop.hpp>
        #include <range/v3/view/subrange.hpp>
        #include <range/v3/view/take.hpp>
        #include <range/v3/algorithm/all_of.hpp>
        #include <string>
        
        using namespace boost::hana;
        using namespace ranges;
        using namespace ranges::views;
        
        auto constexpr is9 = partial(std::equal_to<>{}, 9);
        
        template<typename Range>
        Range fun(Range const& r) {
            if (r.size() == 3) {                   // 3 digits only?
                return r;                              // this is the result
            } else if (all_of(r | take(3), is9)) { // 999?
                return r | take(3);                    // nothing better than this!
            } else {                               // otherwise?
                auto tail = r | drop(1);               // drop the first to get the tail
                if (r.front() < tail.front()) {        // if the first is less the the tip of the tail
                    return fun(tail);                      // then let the first go and recurse on the tail
                } else {                               // otherwise
                    auto result = std::max(                // get the maximum between
                            r | take(3) | to<std::string>, // the current first three
                            fun(tail)   | to<std::string>  // and the result of recursing on the tail
                            );
                    return result;                         // and that's the result
                }
            }
            return r;
        }
        
        int main() {
            std::string s1 = "534535";
            std::string s2 = "23457888976";
            assert((fun(subrange(s1)) | to<std::string>) == std::string{"535"});
            assert((fun(subrange(s2)) | to<std::string>) == std::string{"976"});
        }
        

        该数字被视为一个字符串,并且由于我们需要比较长度为 3 的(子)字符串,因此字典 operator&lt;std::strings 给出的结果与算术 operator&lt; 给出的结果相同两个对应的数字。

        逻辑是:

        • 我们从左边开始,如果需要,向右递归
        • 在只剩下3位的情况下,r.size() == 3,我们全部返回,return r;
        • 在三个前导九的情况下,all_of(r | take(3), is9),我们简单地返回这三个,return r | take(3);
        • 否则,我们在前导 3 位字符串 r | take(3) | to&lt;std::string&gt; 和我们通过在没有第一个数字的序列的其余部分上递归获得的 std::string 之间获取 std::maxfun(tail) | to&lt;std::string&gt;

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-04-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-03-13
          • 2016-05-05
          • 1970-01-01
          相关资源
          最近更新 更多