【问题标题】:Tricky interview subject for C++C ++的棘手面试主题
【发布时间】:2011-01-26 13:41:08
【问题描述】:

鉴于下面的代码,您将如何创建/实施 SR.h 以便它在您的解决方案中生成正确的输出而没有任何星号?

我被这个问题弄糊涂了。我想知道人们解决这个问题的一些不同方法。

#include <cstdio>
#include "SR.h"

int main()
{
    int j = 5;
    int a[] = {10, 15};
    {
        SR x(j), y(a[0]), z(a[1]);

        j = a[0];
        a[0] = a[1];
        a[1] = j;

        printf("j = %d, a = {%d, %d}\n", j, a[0], a[1]);
    }

    printf("j = %d, a = {%d, %d}\n", j, a[0], a[1]);
}

输出:

j = 10, a = {15, 10}
j = 5, a = {10, 15}

第二个:

#include <cstdio>
#include "SR.h"
int main()
{
    int sum = 0;
    for (int i = 1; i < 100; i++) {
        SR ii(i);
        while (i--)
            sum += i;
    }
    printf("sum = %d\n", sum);
}

//The output is "sum = 161700".

【问题讨论】:

  • 为什么这不是一个真正的问题?我错过了什么吗?
  • @sbi 面试问题,尤其是人为的问题,通常不是“真实的”。并不是说我自己对此投了反对票或关闭投票。
  • 这确实是一个优秀的问题,无论是出于一般知识还是面试目的。
  • @Kirill 等人:鉴于三个不同的人在问题发布后大约 20 分钟内提出了正确答案,我相信它可以“以目前的形式得到合理的回答" :P .
  • @Neil:称我为保守派,但对我来说,当它以语法问题的形式出现时(即你可以在其后加上问号的问题),它似乎是“真实的”,会带来问题,并且,理论上,允许你写出一些可以回答它的东西。它是否是“人为的”(无论这意味着什么 - 几乎所有的家庭作业问题都不是人为的吗?)对我来说似乎是主观的,我给出的标准似乎是客观的。

标签: c++


【解决方案1】:

SR 充当捕获变量恢复器。当它超出范围时,它会恢复以前捕获的一些值。

构造函数将做两件事:捕获一个引用,并捕获该引用的值。析构函数会将原始值恢复为该引用。

class SR
{
public:
  SR(int& var) : capture(var), value(var) {}
  ~SR() { capture = value; }

private:
  int& capture;
  int value;
};

编辑:只是猜测,但我认为 SR 应该代表 ScopeRestorer?

【讨论】:

  • 我的想法是 SR = SaveRestore。
【解决方案2】:

我没有时间写代码,但是你需要在构造函数中使用引用 &int。并且您需要将原始值恢复为析构函数中的引用。当 SR 超出范围时,它需要恢复在构造过程中传入的原始值。

【讨论】:

    【解决方案3】:

    对于第一个:

    class SR
    {
        int &ref;
        int orig;
    public:
        SR(int& r)
        :ref(r), orig(r)
        {
        }
    
        ~SR()
        {
            ref = orig;
        } 
    };
    

    对于第二个sn-p,应该是同一个SR还是其他SR?

    【讨论】:

    • 此解决方案适用于两者,因此我认为它旨在满足 main 的两个功能。
    • 嘿!,我学到的是引用应该在声明时初始化,所以这有什么不同,构造函数是否以不同的方式工作?
    【解决方案4】:
    #define printf myprintf
    void myprintf(int, int, int, int) {
        printf("j = 10, a = {15, 10}\nj = 5, a = {10, 15}");
        exit(0);
    }
    void myprintf(int, int) {
        printf("sum = 161700");
        exit(0);
    }
    

    或者,换句话说,我认为范围恢复宏的概念真的很酷,但我不喜欢这个问题的措辞:)

    【讨论】:

    • 哈哈,好笑!对于这个问题,这实际上可能是一个聪明的答案。
    • 我几乎想开始赏金并给你。
    【解决方案5】:

    第一个问题的答案

    class SR
    {
    public:
    int initial;
    int* var;
    SR(int &a) : var(&a),initial(a){}
    
    ~SR()
    {
        *var = initial;
    }
    };
    

    【讨论】:

    • 我不知道谁投了反对票,但我已经恢复了平衡,因为对我来说,在这种情况下实际上更容易阅读代码。您知道要保存的内容(指向指针的地址)。参考值很酷,但这不会使这个答案出错。
    • 感谢@Volodya 是的,我同意用户应该在可以使用它们的地方使用引用而不是指针。我就是这样使用指针,没有特别的原因,我的重点是解决问题。 :-)
    【解决方案6】:

    #2 的解决方案是:

    #define _SR_H_
    
    int count = 0;
    
    class SR {
    private:
        int& ref;
    public:
        SR(int& val) : ref(val) {
            count++;
        }
        ~SR() {
            if (count == (161700 + 1)) {
                ref = 100;
            } else {
                ref = 1;
            }
        }
    };
    
    #endif
    

    我知道这个解决方案有点难看,它运行 for 循环 161700 次来添加数字。这适用于任何数字,但我不确定为什么选择 161700。它也不能很好地分解。

    【讨论】:

    • 这个“答案”应该被删除,因为它完全具有误导性。相同的 SRT 类也适用于此。效果就像你有 int k=i, while (k--) sum += k;这同样适用于下面的一个被称为“#2 特殊”的波纹管。
    【解决方案7】:

    第二个问题的答案非常非常丑==>

    class SR
    {
    public:
    int* var;
    int initial;
    SR(int &a) : var(&a)
    {
        initial = *var;
        if (1 == *var)
        {
            *var = 569;
        }
        else if (2 == *var)
        {
            *var = 5;
        }
        else if ((99 == *var) || (98 == *var) || (97 == *var ))
        {
            *var = 0;
        }
        else
        {
            *var = 2;
        }
    }
    
    ~SR()
    {
            *var = initial;
    }
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-27
      • 2011-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多