很难创建一个按升序显示 n 个数字 (0<n<10) 的所有不同组合的函数
Having a hard time creating a function that displays all different combinations of n numbers (0<n<10)by ascending order
我很难找到其背后的逻辑。我知道递归会有所帮助,但我不知道如何处理它。我的困难在于处理在基本情况下发送/打印数组的时间。我所做的一切我只能迭代最后一个数字而不知道如何处理其他数字。
如果 n 为 2:
$>./a.out | cat -e
01, 02, 03, ..., 09, 12, ..., 79, 89$
如果 n 是 3,事情会变得更难:
012, 013, 014, ..., 123, 124, ..., 134, 135,... 234, ..., 789$
我的代码远不能正常工作
#include <unistd.h>
#include <stdlib.h>
#include <stdbool.h>
void ft_putchar(char c)
{
write(1, &c, 1);
}
bool is_consecutive(int arr[], int n)
{
int last_value = 9;
if ( n <= 0 )
return false;
while ( --n ) {
if ( arr[n] != last_value-- )
return false;
}
return true;
}
void ft_print_screen(int *t, int size)
{
int i;
i = 0;
while (i < size)
{
ft_putchar(t[i] + '0');
i++;
}
if (is_consecutive(t, size) != true)
{
ft_putchar(',');
ft_putchar(' ');
}
}
void ft_print_combn(int n)
{
int i;
int tab[n];
i = 0;
if (n == 1)
while (i < 10)
{
ft_putchar(i + '0');
i++;
}
while (i < n)
{
tab[i] = 0;
i++;
}
while (tab[0] <= (10 - n) && n > 1)
{
ft_print_screen(tab, n);
tab[n - 1]++;
i = n;
while (i && n > 1)
{
i--;
if (tab[i] > 9)
{
tab[i - 1]++;
tab[i] = 0;
}
}
}
}
void main(int argc, char *argv[])
{
int x = atoi(argv[1]);
ft_print_combn(x);
}
这是一个您应该能够适应您的需求的解决方案。该代码有条件地使用 stdio 或裸 write
调用。只需将 USE_STDIO
的定义更改为 #define USE_STDIO 0
以使其使用裸 write
调用(或简单地删除条件化)。
请注意,我使用 int
而不是 size_t
作为字符串长度,因为它们永远不会大于字符集大小(即 10),但您当然可以使用 size_t
如果你愿意的话。
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#define USE_STDIO 1
void my_write(int len, char buf[len])
{
#if USE_STDIO
printf("%.*s", len, buf);
#else
write(1, buf, len);
#endif
}
void my_write_s(char *buf)
{
my_write(strlen(buf), buf);
}
void show(bool first, int len, char buf[len])
{
if (! first) {
my_write_s(", ");
}
my_write(len, buf);
}
void end(void)
{
my_write_s("$\n");
}
void gen_combs2(bool first, char *buf, int off, int m, char chars[m], int n)
{
if (n == 0) {
show(first, off, buf);
return;
}
for (int i = 0; i < m + 1 - n ; i++) {
buf[off] = chars[i];
gen_combs2(first, buf, off + 1, m - i - 1, chars + i + 1, n - 1);
first = false;
}
}
void gen_combs(char *chars, int n)
{
int m = strlen(chars);
char buf[n];
gen_combs2(true, buf, 0, m, chars, n);
end();
}
int main(void)
{
gen_combs("0123456789", 1);
gen_combs("0123456789", 2);
gen_combs("0123456789", 3);
return 0;
}
我很难找到其背后的逻辑。我知道递归会有所帮助,但我不知道如何处理它。我的困难在于处理在基本情况下发送/打印数组的时间。我所做的一切我只能迭代最后一个数字而不知道如何处理其他数字。
如果 n 为 2:
$>./a.out | cat -e
01, 02, 03, ..., 09, 12, ..., 79, 89$
如果 n 是 3,事情会变得更难:
012, 013, 014, ..., 123, 124, ..., 134, 135,... 234, ..., 789$
我的代码远不能正常工作
#include <unistd.h>
#include <stdlib.h>
#include <stdbool.h>
void ft_putchar(char c)
{
write(1, &c, 1);
}
bool is_consecutive(int arr[], int n)
{
int last_value = 9;
if ( n <= 0 )
return false;
while ( --n ) {
if ( arr[n] != last_value-- )
return false;
}
return true;
}
void ft_print_screen(int *t, int size)
{
int i;
i = 0;
while (i < size)
{
ft_putchar(t[i] + '0');
i++;
}
if (is_consecutive(t, size) != true)
{
ft_putchar(',');
ft_putchar(' ');
}
}
void ft_print_combn(int n)
{
int i;
int tab[n];
i = 0;
if (n == 1)
while (i < 10)
{
ft_putchar(i + '0');
i++;
}
while (i < n)
{
tab[i] = 0;
i++;
}
while (tab[0] <= (10 - n) && n > 1)
{
ft_print_screen(tab, n);
tab[n - 1]++;
i = n;
while (i && n > 1)
{
i--;
if (tab[i] > 9)
{
tab[i - 1]++;
tab[i] = 0;
}
}
}
}
void main(int argc, char *argv[])
{
int x = atoi(argv[1]);
ft_print_combn(x);
}
这是一个您应该能够适应您的需求的解决方案。该代码有条件地使用 stdio 或裸 write
调用。只需将 USE_STDIO
的定义更改为 #define USE_STDIO 0
以使其使用裸 write
调用(或简单地删除条件化)。
请注意,我使用 int
而不是 size_t
作为字符串长度,因为它们永远不会大于字符集大小(即 10),但您当然可以使用 size_t
如果你愿意的话。
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#define USE_STDIO 1
void my_write(int len, char buf[len])
{
#if USE_STDIO
printf("%.*s", len, buf);
#else
write(1, buf, len);
#endif
}
void my_write_s(char *buf)
{
my_write(strlen(buf), buf);
}
void show(bool first, int len, char buf[len])
{
if (! first) {
my_write_s(", ");
}
my_write(len, buf);
}
void end(void)
{
my_write_s("$\n");
}
void gen_combs2(bool first, char *buf, int off, int m, char chars[m], int n)
{
if (n == 0) {
show(first, off, buf);
return;
}
for (int i = 0; i < m + 1 - n ; i++) {
buf[off] = chars[i];
gen_combs2(first, buf, off + 1, m - i - 1, chars + i + 1, n - 1);
first = false;
}
}
void gen_combs(char *chars, int n)
{
int m = strlen(chars);
char buf[n];
gen_combs2(true, buf, 0, m, chars, n);
end();
}
int main(void)
{
gen_combs("0123456789", 1);
gen_combs("0123456789", 2);
gen_combs("0123456789", 3);
return 0;
}