【问题标题】:How not to print duplicate combinations in c如何不在c中打印重复的组合
【发布时间】:2020-08-02 11:18:36
【问题描述】:

我在数组中存储了一系列组合,例如:

{“嘿”、“嗨”、“你好”}

我必须在所有组合上盖章,例如:

  1. {嘿,你好,你好}

  2. {嘿嘿嘿}

  3. {你好,嗨,嗨}

等等......直到这里使用回溯很容易,但我的问题是:

我不能标记重复的组合,例如:

  1. {嘿,你好,你好}

  2. {嗨,你好,嘿}

您如何看待每个值的位置不同但这些组合中的单词相同。

如何删除这些重复的组合?有什么想法吗?

只是为了更清楚我的问题:

如果我有这个数组:{"hi", "hey"},这些是我可以打印的值:

  1. 你好,嘿
  2. 嗨,嗨
  3. 嘿嘿
  4. 你好

我无法打印这些值:

  1. 嗨,嗨(因为已经有组合:嗨,嗨)

【问题讨论】:

  • 当您进行组合时,如何将它们按排序顺序存储在一个集合中。因此,当您进行新组合时,只需检查该向量是否存在于集合中。
  • 这个set是c语言定义的?没听说过
  • 我试过了,但是其他好的解决方案都被跳过了
  • 在组合学术语中,这被描述为将整数 n 划分为 m 个整数的总和,其中 n 是每个“组合”中的项目数,m 是您的“组合”中的数量初始序列。 (您的示例对于 n 和 m 都有 3,但它们通常不必相同,并且您的问题描述没有明确说明它们是否必须针对您的特定问题。)(顺便说一下,避免使用“组合”为此;在这样的上下文中,使用该术语或在数学中具有不同的目的。)
  • 对不起,我还没有找到更好的解释方式

标签: c


【解决方案1】:

我想数组中的所有元素都是不同的。

有重复需要在打印时改变元素的顺序,没有重复就可以让元素按顺序排列。

一种方法可以是:

#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 $ 

【讨论】:

    【解决方案2】:

    如何使用这种方法生成所需的数组。

    考虑生成的新数组将有'x' hellos、'y' his 和'z' heys。 (我们正在考虑它们的数量,因为它们在结果数组中的位置对我们来说并不重要)。

    现在,我们知道要生成/查找的数组的长度是 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
                }
            }
        }
    }
    

    希望这会有所帮助。如果有不清楚的地方请告诉我。

    【讨论】:

    • 感谢您的努力,但这个解决方案永远不会奏效,因为我使用回溯方式来解决问题,并且如果我更改数组值:{“hey”、“hi”、“hello” , "bye"} 这个解决方案会过时。无论如何谢谢:)
    • 您的代码在C++ 中,并且问题不包含c++ 标记。
    【解决方案3】:

    一个简单的实现

    #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);
    }
    

    注意:在调用combine之前,数组words的最后一个元素必须设置为NULL。在这种情况下不需要它,因为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
    

    【讨论】:

      【解决方案4】:

      下面的代码会给出你想要的结果:

      (它是用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();
              }
          }
      }
      

      【讨论】:

      • 感谢您的努力,但此解决方案不正确,您打印所有组合,甚至是我不想要的重复项 :(,无论如何这是 java 我的问题在于 c 语言:')。还是谢谢
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多