Я пытаюсь преобразовать эту вещь (алгоритм Шеннона-Фано) из паскаля в c #:

program ShennonFano;
uses crt;
const
  a :array[1..6] of char = ('a','b','c','d','e','f');
  af:array[1..6] of integer = (10, 8, 6, 5, 4, 3);


procedure SearchTree(branch:char; full_branch:string; start_pos:integer; end_pos:integer);
var
  dS:real; 
  i, m, S:integer; 
  c_branch:string;
begin

  if (a<>' ') then c_branch := full_branch + branch
  else c_branch := '';


  if (start_pos = end_pos) then
  begin
    WriteLn(a[start_pos], ' = ', c_branch);
    exit;
  end;


  dS := 0;
  for i:=start_pos to end_pos do dS:= dS + af[i];
  dS := dS/2;


  S := 0;
  i := start_pos;
  m := i;
  while ((S+af[i]<dS) and (i<end_pos)) do
  begin
    S := S + af[i];
    inc(i); inc(m);
  end;


  SearchTree('1', c_branch, start_pos, m);

  SearchTree('0', c_branch, m+1, end_pos);

end;

begin
  WriteLn('Press <enter> to show');
  ReadLn;
  ClrScr;

  SearchTree(' ',' ', 1, 6);
  ReadLn;
end;

А вот мой код в C #:

namespace Shannon_Fano_Alg
{
    class Program
    {
        static char[] a = { 'a', 'b', 'c', 'd', 'e', 'f' };
        static int[] af = { 10, 8, 6, 5, 4, 3 };
        static bool first = true;

        static void Search(char branch, string full_branch, int startPos, int endPos)
        {
            double dS;
            int m, i, S;
            string c_branch;
            if (first)
            {
                c_branch = "";
                first = false;
            }
            else
            {
                c_branch = full_branch + branch;
            }

            if (startPos == endPos)
            {
                Console.WriteLine(a[startPos] + " = " + c_branch);
            }

            dS = 0;
            for (i = startPos; i<endPos; i++)
            {
                dS += af[i];
            }

            dS /= 2;


            S = 0;
            i = startPos;
            m = i;
            while (S + af[i] < dS && i<endPos)
            {
                S += af[i];
                i++;
            }

            Search('1', c_branch, startPos, m);
            Search('0', c_branch, m + 1, endPos);

        }

        static void Main(string[] args)
        {
            Program.Search(' ', " ", 0, 5);
            Console.ReadKey();
        }

    }
}

Но, к сожалению, мой код зацикливается бесконечно, и я получаю что-то вроде этого: введите описание изображения здесь Этот алгоритм отлично работает на паскале, поэтому я думаю, что я перевел его неправильно. Пожалуйста, помогите мне понять, где моя ошибка. Заранее спасибо.

0
coldembrace 3 Апр 2017 в 11:32

2 ответа

Лучший ответ

В дополнение к ответу BugFinder.

Паскаль имеет это:

while ((S+af[i]<dS) and (i<end_pos)) do
begin
  S := S + af[i];
  inc(i); inc(m);
end;

У вашего C # есть это:

while (S + af[i] < dS && i<endPos)
{
   S += af[i];
   i++;
}

Вы не увеличиваете m, поэтому добавьте m ++; после i ++;

2
PaulF 3 Апр 2017 в 08:40

В коде паскаля вы пропустили завершающую часть «Мне больше нечего делать»

if (start_pos = end_pos) then
  begin
    WriteLn(a[start_pos], ' = ', c_branch);
    exit;
  end;

Вы пропустили выход .. в вашем коде C #, так что он просто продолжает цикл

    if (startPos == endPos)
    {
        Console.WriteLine(a[startPos] + " = " + c_branch);
    }

Вам нужно добавить возврат после этого Console.WriteLine, например

        if (startPos == endPos)
        {
            Console.WriteLine(a[startPos] + " = " + c_branch);
            return;
        }
2
Rudy Velthuis 21 Май 2017 в 08:45