Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
2 / 2 / 0
Регистрация: 17.05.2012
Сообщений: 13
1

Рекурсивный перебор. Вылет за границы массива

11.04.2013, 18:08. Показов 2187. Ответов 11
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
ка, состоящая из попарно различных символов (буквы латинского алфавита и цифры). Требуется вывести все перестановки символов данной строки в алфавитном порядке.
Ввод:
AB
Вывод:
AB
BA
Ввод:
IOX
Вывод:
IOX
IXO
OIX
OXI
XIO
XOI

Написал код, вроде должно работать. Но если по алгоритму, то вылетает за границы массива. А если в цикле сделать на одну итерацию меньше то выводит не то, что нужно.

Вылет за границы в 33 строке в общем коде.
Вот кусочек, в котором вылетает, ниже полный код.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
listBox1.Items.Clear();
            s = richTextBox1.Text.ToString();
            n = s.Length;
            for(int i=0; i<n-1; i++)
                for(int j=0; j<n-i; j++)
                    if(s[j]>s[j+1])
                    {
                        char[] arr = s.ToCharArray();
                        ch = arr[j];
                        arr[j] = arr[j+1];
                        arr[j + 1] = ch;
                        s = new string(arr);
                    }
 
Полный код:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
 
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        private string s;
        bool[] used = new bool[10];
        int[] a = new int[10];
        int n;
        char ch;
 
        private void button1_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
            s = richTextBox1.Text.ToString();
            n = s.Length;
            for(int i=0; i<n-1; i++)
                for(int j=0; j<n-i; j++)
                    if(s[j]>s[j+1])
                    {
                        char[] arr = s.ToCharArray();
                        ch = arr[j];
                        arr[j] = arr[j+1];
                        arr[j + 1] = ch;
                        s = new string(arr);
                    }
            for (int i = 0; i < n; i++)
                used[i] = true;
            dfs(1);
        }
 
        public void dfs(long v)
        {
            char[] arr= new char[n];
            if (v == (n + 1))
            {
                for (int i = 0; i < n; i++)
                {
                    arr[i] = s[a[i]];
                }
                string ps = new string(arr);
                listBox1.Items.Add(ps);
            }
            for(int i=0; i<n; i++)
                if(used[i])
                {
                    a[v] = i;
                    used[i] = false;
                    dfs(v+1);
                    used[i] = true;
                }
        }
    }
}
Помогите пожалуйста, не могу найти, где вылетает.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
11.04.2013, 18:08
Ответы с готовыми решениями:

Рекурсивный перебор элементов массива любой размерности
Так долго вожусь и все равно ничего : public static void _ForEach&lt;T&gt;(this Array a , Func&lt;T,T&gt;...

Вылет за границы массива
Пожайлуста помогите найти ошибку, она возникает когда добавляю следующую строчку в main Monitor...

Перебор двумерного массива и выход за границы массива
Добрый день, у меня возникла такая проблема: есть шахматное поле 10х10 Данная часть кода...

Вылет за границы вектора
Привет. При компиляции вылетаю за границы, я не понимаю, как это происходит и как поправить. ...

11
Заблокирован
11.04.2013, 18:13 2
C#
1
for(int j=0; j<n-i-1; j++)
1
192 / 192 / 29
Регистрация: 03.12.2009
Сообщений: 853
11.04.2013, 18:13 3
Вместо
Цитата Сообщение от serguk071 Посмотреть сообщение
for(int j=0; j<n-i; j++)
надо
C#
1
for(int j=0; j<n-i-1; j++)
Т.к. когда i=0 , j будет = n, что есть s.length и тут получается выход за пределы массива
1
2 / 2 / 0
Регистрация: 17.05.2012
Сообщений: 13
11.04.2013, 18:31  [ТС] 4
Цитата Сообщение от da1z Посмотреть сообщение
Вместо
надо
C#
1
for(int j=0; j<n-i-1; j++)
Т.к. когда i=0 , j будет = n, что есть s.length и тут получается выход за пределы массива
Пробовал. Я же написал выше, что тогда выводит неправильный ответ. А код такой же один в один на фри паскале работает идеально.

Добавлено через 1 минуту
Цитата Сообщение от serguk071 Посмотреть сообщение
Если в цикле сделать на одну итерацию меньше то выводит не то, что нужно.
Сейчас скину прокомментированный код, чтобы легче читать было.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
 
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        private string s; // строка символов
        bool[] used = new bool[10]; // метка того, использовали ли мы элемент под номером i в перестановке
        int[] a = new int[10]; // текущая перестановка
        int n;  // n - длина строки
        char ch;
 
        private void button1_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
            s = richTextBox1.Text.ToString();
            n = s.Length; // длина строки
            for(int i=0; i<n-1; i++)
                for (int j = 0; j < n - i; j++)
                    if (s[j] > s[j + 1]) // это сортировка символов строки, потому что перестановки генерируются в алфавитном порядке
                    {
                        char[] arr = s.ToCharArray();
                        ch = arr[j];
                        arr[j] = arr[j+1];
                        arr[j + 1] = ch;
                        s = new string(arr);
                    }
            for (int i = 0; i < n; i++)
                used[i] = true; // обнуление
            dfs(1); // запуск рекурсии
        }
 
        public void dfs(long v) // процедура генерации
        {
            char[] arr= new char[n];
            if (v == n + 1) // если перестановка сгенерирована
            {
                for (int i = 0; i < n; i++)
                {
                    arr[i] = s[a[i]]; // то выводим ее посимвольно
                }
                string ps = new string(arr);
                listBox1.Items.Add(ps);
            }
            for (int i = 0; i < n; i++) // иначе ищем элемент, который мы поставим на v-ое место
                if (used[i]) // если элемент не использован
                {
                    a[v] = i; // то ставим его на v-ое место
                    used[i] = false; // метим, что это элемент мы брали
                    dfs(v + 1); // переходим на следующую позицию
                    used[i] = true; // откат обратно
                }
        }
    }
}
Добавлено через 4 минуты
А вот тот же код на паскале:

Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
var s:string; // строка символов
    used:array[0..10] of boolean; // метка того, использовали ли мы элемент под номером i в перестановке
    a:array[0..10] of longint; // текущая перестановка
    i,n,j:longint; // n - длина строки, i,j - счетчики
    ch:char;
 
procedure dfs(v:longint); // процедура генерации
var i:longint; // счетчик
begin 
 if (v=n+1) // если перестановка сгенерирована
  then
   begin
    for i:= 1 to n do
     write(s[a[i]]);  // то выводим ее посимвольно
     writeln;
    exit;
   end;
  for i:= 1 to n do // иначе ищем элемент, который мы поставим на v-ое место
   if used[i] then // если элемент не использован
    begin
     a[v]:=i; // то ставим его на v-ое место
     used[i]:=false; // метим, что это элемент мы брали
     dfs(v+1); // переходим на следующую позицию
     used[i]:=true; // откат обратно
    end;
end;
 
 
begin
 readln(s); // ввод строки
 n:=length(s); // длина строки
 for i:= 1 to n-1 do  
  for j:= 1 to n-i do
   if (s[j]>s[j+1]) // это сортировка символов строки, потому что перестановки генерируются в алфавитном порядке
     then
      begin
       ch:=s[j];
       s[j]:=s[j+1];
       s[j+1]:=ch;
      end;
 for i:= 1 to n do
  used[i]:=true; // обнуление
 dfs(1); // запуск рекурсии
end.
Добавлено через 1 минуту
Цитата Сообщение от AIMaster Посмотреть сообщение
C#
1
for(int j=0; j<n-i-1; j++)
Пробовал. Я же написал выше, что тогда работает, но выводит неправильный ответ. А код такой же один в один на фри паскале работает идеально.

Может я криворуко переписал. Тогда простите

Ниже код есть, сравните если не сложно.

Спасибо за помощь и попытки помощи огромное!)
0
192 / 192 / 29
Регистрация: 03.12.2009
Сообщений: 853
11.04.2013, 18:45 5
Цитата Сообщение от serguk071 Посмотреть сообщение
Пробовал. Я же написал выше, что тогда работает, но выводит неправильный ответ.
Тогда ищите ошибку в алгоритме
1
2 / 2 / 0
Регистрация: 17.05.2012
Сообщений: 13
11.04.2013, 18:47  [ТС] 6
Цитата Сообщение от da1z Посмотреть сообщение
Тогда ищите ошибку в алгоритме
Но почему на паскале то работает?)))))
Вот в чем самый большой вопрос
0
192 / 192 / 29
Регистрация: 03.12.2009
Сообщений: 853
11.04.2013, 18:48 7
дел
1
2 / 2 / 0
Регистрация: 17.05.2012
Сообщений: 13
11.04.2013, 18:50  [ТС] 8
Цитата Сообщение от da1z Посмотреть сообщение
дел
Что простите?)
0
192 / 192 / 29
Регистрация: 03.12.2009
Сообщений: 853
11.04.2013, 18:54 9
Покажите, что выводит(Не правильный вариант)
1
2 / 2 / 0
Регистрация: 17.05.2012
Сообщений: 13
11.04.2013, 19:02  [ТС] 10
Цитата Сообщение от da1z Посмотреть сообщение
Покажите, что выводит(Не правильный вариант)
Прикрепил вывод в трех случаях
Миниатюры
Рекурсивный перебор. Вылет за границы массива   Рекурсивный перебор. Вылет за границы массива   Рекурсивный перебор. Вылет за границы массива  

0
192 / 192 / 29
Регистрация: 03.12.2009
Сообщений: 853
11.04.2013, 19:16 11
C#
1
dfs(1); // запуск рекурсии
Мне кажется тут с нулём надо вызвать
0
2 / 2 / 0
Регистрация: 17.05.2012
Сообщений: 13
11.04.2013, 19:27  [ТС] 12
Цитата Сообщение от da1z Посмотреть сообщение
C#
1
dfs(1); // запуск рекурсии
Мне кажется тут с нулём надо вызвать
Ничего не выводит совсем.

У меня уже просто аж интерес, где же ошибка...
0
11.04.2013, 19:27
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
11.04.2013, 19:27
Помогаю со студенческими работами здесь

Рекурсивный перебор
Здравствуйте, есть задача:...

Рекурсивный перебор
Здравствуйте, решаю задачу о рюкзаке и не могу понять почему возвращает все время 0. Имеется...

рекурсивный перебор
Дана строка, состоящая из M (2 ≤ M ≤ 8) попарно различных символов (буквы латинского алфавита и...

Задача на рекурсивный перебор
В выражении ((((1?2)?3)?4)?5)?6 . Нужно заменить знаки вопроса на знаки +-*/ чтобы в итоге...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru