Как не печатать повторяющиеся комбинации в c - PullRequest
0 голосов
/ 02 августа 2020

Я сохранил в массиве последовательность комбинаций, например:

{«привет», «привет», «привет»}

и я должен отметить все комбинации, например:

  1. {эй, привет, привет}

  2. {эй, эй, эй}

  3. {hello, hi, hi}

et c ... и до этого момента легко использовать обратный поиск, но моя проблема:

Я не могу штамповать повторяющиеся комбинации, например:

  1. {эй, привет, привет}

  2. {привет, привет, эй}

как вы видите, положение каждого значения отличается, но в этих комбинациях есть одни и те же слова.

Как я могу удалить эти повторяющиеся комбинации? Есть идеи?

просто для большей ясности мой вопрос:

если у меня есть этот массив: {"привет", "эй"}, это значения, которые я могу напечатать:

  1. привет, эй
  2. привет, привет
  3. эй, эй
  4. привет
  5. эй

Я не могу напечатать эти значения:

  1. эй, привет (потому что уже есть комбинация: привет, эй)

Ответы [ 4 ]

1 голос
/ 02 августа 2020

Я полагаю, что все элементы в массиве разные.

Чтобы иметь дубликаты, необходимо изменить порядок элементов при их печати, затем, чтобы не было дубликатов, достаточно ввести элементы в порядок.

Способ выполнения может быть:

#include <stdio.h>
#include <malloc.h>

void combine(char ** words, char ** begin, int nwords, int n2produce, int rank)
{
  if (rank == nwords-1) {
    int i;
    
    for (i = 0; i != nwords - n2produce; i += 1)
      printf("%s ", begin[i]);
    while (i++ != nwords)
      printf("%s ", words[rank]);
    putchar('\n');
  }
  else {
    for (int i = 1; i <= n2produce; i += 1) {
      begin[nwords - n2produce + i - 1] = words[rank];
      combine(words, begin, nwords, n2produce - i, rank + 1);
    }
    combine(words, begin, nwords, n2produce, rank + 1);
  }
}

int main(int argc, char ** argv)
{
  if (argc != 1) {
    char ** begin = malloc((argc - 1) * sizeof(*begin));
  
    combine(argv+1, begin, argc-1, argc-1, 0);
    free(begin);
  }
  return 0;
}

Компиляция и выполнение:

pi@raspberrypi:/tmp $ gcc -Wall -g c.c
pi@raspberrypi:/tmp $ ./a.out aze
aze 
pi@raspberrypi:/tmp $ ./a.out aze qsd
aze qsd 
aze aze 
qsd qsd 
pi@raspberrypi:/tmp $ ./a.out aze qsd wxc
aze qsd wxc 
aze qsd qsd 
aze wxc wxc 
aze aze qsd 
aze aze wxc 
aze aze aze 
qsd wxc wxc 
qsd qsd wxc 
qsd qsd qsd 
wxc wxc wxc 
pi@raspberrypi:/tmp $ 
0 голосов
/ 02 августа 2020

Простая реализация

#include <stdio.h>
#include <stdlib.h>

static char **stack;
static int stacksize;

void combine(char *words[], int tos /* top of stack */)
{
   if (tos == stacksize) {
       for (int i = 0; i < tos; ++i)
           printf("%s%c", stack[i], i == tos - 1 ? '\n' : ' ');
       return;
   }

   for (int save_tos = tos; *words; ++words, tos = save_tos)
       while (tos < stacksize) {
           stack[tos++] = *words;
           combine(words + 1, tos);
       }
}

int main (int argc, char *argv[])
{
    stacksize = argc - 1;
    stack = malloc(stacksize * sizeof *stack);
    if (stack)
        combine(&argv[1], 0);
}

Примечание : последний элемент массива words должен быть установлен на NULL перед вызовом combine. В этом случае это не нужно, потому что argv[argc] является нулевым указателем при запуске программы.


Тест:

$ ./a.out aaa bbb ccc
aaa bbb ccc
aaa bbb bbb
aaa ccc ccc
aaa aaa bbb
aaa aaa ccc
aaa aaa aaa
bbb ccc ccc
bbb bbb ccc
bbb bbb bbb
ccc ccc ccc
0 голосов
/ 02 августа 2020

Приведенный ниже код даст желаемый результат:

(Он написан на Java, закомментируйте, если вам нужна помощь в переводе на язык C)

Результат:

hey hey hey 
hey hey hi 
hey hey hello 
hey hey 
hey hi hey 
hey hi hi 
hey hi hello 
hey hi 
hey hello hey 
hey hello hi 
hey hello hello 
hey hello 
hey 
hi hey hey 
hi hey hi 
hi hey hello 
hi hey 
hi hi hey 
hi hi hi 
hi hi hello 
hi hi 
hi hello hey 
hi hello hi 
hi hello hello 
hi hello 
hi 
hello hey hey 
hello hey hi 
hello hey hello 
hello hey 
hello hi hey 
hello hi hi 
hello hi hello 
hello hi 
hello hello hey 
hello hello hi 
hello hello hello 
hello hello 
hello

Используемый рекурсивный «алгоритм»:

public static void alg (ArrayList<String[]> result, String list [], String [] left, int current_index){
    if ( current_index == list.length ) {
        return ;
    }

    for ( int i = 0; i < list.length ; i ++ ){
        String [] new__list = concat(left, new String [] {list[i]});
        alg (result, list, new__list, current_index+1);

        result.add(new__list);
    }

}



Полный код:

import java.util.ArrayList;
import java.util.Arrays;

public class Main {
    
    //concatenate 2 string arrays
    static String [] concat (String [] s1, String [] s2){
        String [] result = new String [s1.length + s2.length];
        
        for ( int i = 0 ; i < result.length ; i ++ ){
            if ( i < s1.length){
                result[i] = s1[i];
            }else {
                result[i] = s2 [i - s1.length];
            }
        }
        return result;
    }

    //The algorithm
    public static void alg (ArrayList<String[]> result, String list [], String [] left, int current_index){
        if ( current_index == list.length ) {
            return ;
        }
        
        for ( int i = 0; i < list.length ; i ++ ){
            String [] new__list = concat(left, new String [] {list[i]});
            alg (result, list, new__list, current_index+1);
            
            result.add(new__list);
        }
        
    }
    
    public static void main(String[] args) {
        
        String [] list = {"hey", "hi", "hello"};
        ArrayList <String[]> result = new ArrayList <String[]> () ;
        
        alg (result, list, new String [] {}, 0);
        
        //Print the result list
        for ( int i = 0 ; i < result.size() ; i ++ ){
            for (int j = 0 ; j < result.get(i).length ; j ++ ){
                System.out.print(result.get(i)[j] + " ");
            }
            System.out.println();
        }
    }
}
0 голосов
/ 02 августа 2020

Как насчет этого подхода для генерации требуемых массивов.

Учтите, что новый сгенерированный массив будет иметь 'x' привет, 'y' его и 'z' привет. (Мы рассматриваем их количество, потому что их положение в результирующем массиве для нас не имеет значения).

Теперь мы знаем, что длина массива, который мы хотим сгенерировать / найти, равна 3.

Следовательно, мы имеем

x + y + z = 3

Теперь наша задача сводится к поиску подходящих значений x, y и z, которые удовлетворяют приведенное выше уравнение.

Мы можем легко сделать это, используя три цикла for

for(int x=0;x<=3;++x)
{
    for(int y=0;y<=3;++y)
    {
        for(int z=0;z<=3;++z)
        {
            if(x+y+z==3)
            {
                cout<<"Hello : "<<x<<endl;
                cout<<"Hi : "<<y<<endl;
                cout<<"Hey : "<<z<<endl;
                // you will have to construct an array here,
                // I leave that task upto you
            }
        }
    }
}

Надеюсь, это поможет. Пожалуйста, дайте мне знать, если какая-либо часть непонятна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...