C#返回一个完全不相关且看似随机的整数?

时间:2018-11-05 12:38:52

标签: c# variables

我目前是C#的初学者,但是我遇到了这个问题,作为python用户,该错误对我没有任何意义。我试图找到一个修复程序,但是我不知道要搜索什么或如何描述错误,所以请帮忙!

CREATE TABLE test_ ( num_ NUMBER);


INSERT INTO test_ VALUES (12);
INSERT INTO test_ VALUES (3);
INSERT INTO test_ VALUES (12);
INSERT INTO test_ VALUES (8);
INSERT INTO test_ VALUES (10);
INSERT INTO test_ VALUES (4);
INSERT INTO test_ VALUES (4);
INSERT INTO test_ VALUES (2);
INSERT INTO test_ VALUES (7);
INSERT INTO test_ VALUES (10);
INSERT INTO test_ VALUES (10);
INSERT INTO test_ VALUES (11);
INSERT INTO test_ VALUES (12);
INSERT INTO test_ VALUES (11);
INSERT INTO test_ VALUES (4);

COMMIT;


CREATE OR REPLACE TYPE T_NUMBER AS TABLE OF NUMBER;


DECLARE
  lv_numbers T_NUMBER;
  lv_result VARCHAR2(32000);

  /* Convert collection of number to VARCHAR2
   *
   * @param pi_numbers    collection to process
   * @param pi_separator  separator
   * @return              pi_numbers converted to VARCHAR2 with pi_separator as separator
  */
  FUNCTION toVarchar2(
    pi_numbers   T_NUMBER,
    pi_separator VARCHAR2 DEFAULT ','
  )
  RETURN VARCHAR2
  IS
    lv_result VARCHAR2(4000);
  BEGIN
    FOR i IN 1..pi_numbers.COUNT LOOP
      lv_result := lv_result || pi_numbers(i) || pi_separator;  
    END LOOP;
    lv_result := RTRIM(lv_result, pi_separator);
    RETURN lv_result;
  END toVarchar2;

  /* Roll collection to left 
   *
   * @param  pi_numbers   collection to process
   * @return              rolled colletion
  */
  FUNCTION rollLeft(
    pi_numbers   T_NUMBER
  )
  RETURN T_NUMBER
  IS
    lv_result     T_NUMBER;
    lv_currentTop NUMBER;
  BEGIN
    lv_result := pi_numbers;

    IF lv_result.COUNT > 1 THEN
      lv_currentTop := lv_result(1);
      FOR i IN 2..lv_result.COUNT LOOP
        lv_result(i-1) := lv_result(i);  
      END LOOP;
      lv_result(lv_result.COUNT) := lv_currentTop;
    END IF;
    RETURN lv_result;
  END rollLeft;

  /* Split collection to a grup in which we have items with SUM equal to pi_sum
   *
   * @param  pi_numbers  collection to process
   * @param  pi_sum      our goal sum
   * @return             result of split
  */
  FUNCTION split_(
    pi_numbers T_NUMBER,
    pi_sum     NUMBER
  )
  RETURN VARCHAR2
  IS
    lv_groupSeparator  CONSTANT VARCHAR2(1) := '|';
    lv_result          VARCHAR2(4000);
    lv_numbersInGroup  T_NUMBER := new T_NUMBER();
    lv_toFartherSplit  T_NUMBER;
    lv_currentSum      NUMBER   := 0;
    lv_allProcessed    BOOLEAN  := FALSE;
  BEGIN
    IF pi_numbers.COUNT > 0 THEN

      lv_currentSum := pi_numbers(1);
      lv_numbersInGroup.EXTEND;
      lv_numbersInGroup(lv_numbersInGroup.COUNT) := pi_numbers(1);

      FOR i IN 2..pi_numbers.COUNT LOOP
        IF lv_currentSum + pi_numbers(i) <= pi_sum THEN
          lv_currentSum := lv_currentSum + pi_numbers(i);
          lv_numbersInGroup.EXTEND;
          lv_numbersInGroup(lv_numbersInGroup.COUNT) := pi_numbers(i);
        END IF;
        IF lv_currentSum = pi_sum THEN
          EXIT;
        END IF;  
      END LOOP;

      IF lv_currentSum = pi_sum THEN
        lv_result         := toVarchar2(lv_numbersInGroup)  || lv_groupSeparator;
        lv_toFartherSplit := pi_numbers MULTISET EXCEPT lv_numbersInGroup;
      ELSE 
        lv_toFartherSplit := rollLeft(pi_numbers => pi_numbers);
        IF lv_toFartherSplit(lv_toFartherSplit.COUNT) < lv_toFartherSplit(1) THEN
          lv_result       := 'NotUsed:' || toVarchar2(pi_numbers);
          lv_allProcessed := TRUE;
        END IF;
      END IF;  

      IF lv_allProcessed = FALSE THEN
        lv_result := lv_result || 
                     split_(
                       pi_numbers => lv_toFartherSplit, 
                       pi_sum     => pi_sum
                     );
      END IF;

    END IF;


    RETURN lv_result;

  END split_;

BEGIN

  SELECT num_
    BULK COLLECT INTO lv_numbers
    FROM TEST_
   ORDER BY num_ desc;

  lv_result := split_(
                 pi_numbers => lv_numbers, 
                 pi_sum     => 30
               );

  dbms_output.put_line(lv_result);

END;
/

2 个答案:

答案 0 :(得分:2)

Console.Read();确实读取下一个字符,但作为其int表示。您将需要使用Console.ReadLine();,但是现在您面临另一个问题,Console.ReadLine();返回的是字符串而不是int,因此现在需要转换它。在.NET World中,您可以这样做:

string userInput = Console.ReadLine();
int userInputNumber = Convert.ToInt32(userInput);

这是不安全的,因为用户输入的内容可能不是数字,这会使程序崩溃。当然,如果您只是开始并制作“ Hello World”应用程序,那么这可能不是您最大的担心。
如果您有兴趣,我还是会发布更好的版本:

string userInput = Console.ReadLine();
int userInputNumber;
if (int.TryParse(userInput, out userInputNumber))
{
    // Do code here with userInputNumber as your number
}

在C#中(像每一种现代语言一样),我们有一些Syntatic Sugar使它更简短但也更难以阅读:

if (int.TryParse(Console.ReadLine(), out int userInputNumber))
{
    //Do code here
}

答案 1 :(得分:1)

您需要在CalculateAge函数中使用console.ReadLine()而不是console.Read()。 请参考以下答案以了解Console.Read和console.ReadLine之间的区别: Difference between Console.Read() and Console.ReadLine()?

但是我建议您还添加一个tryParse,以便在将输入的值转换为int之前验证输入的值是否为整数

类似这样的东西:

    static void CalculateAge()
    {
        Console.WriteLine("Enter your year of birth ");
        Console.Write("> ");
        string input = Console.ReadLine();
        int date = 2018;
        Int32.TryParse(input, out date);
        int age = (2018 - date);
        Console.Write("You are " + (age));
        Console.ReadLine();
    }

如果不希望它的默认值是2018,则可以有另一个实现。例如添加while循环,而tryParse!= false,然后继续请求输入。