在 C 中只打印一次数组中的所有元素?

时间:2021-01-28 19:47:33

标签: arrays c loops printf unique

我在 C 中创建了一个数组,我知道如何打印数组中的每个元素,但无法弄清楚如何不打印重复的元素,或者更准确地说,就像我在标题中问的那样,如何只打印一次所有元素?

例如我的数组是:import plotly.express as px df = px.data.tips() fig = px.box(df, x="time", y="total_bill", points="all") f = fig.full_figure_for_development(warn=False) fig.update_layout(title_text="", paper_bgcolor='rgba(255,255,255,1)',\ plot_bgcolor='rgba(255,255,255,1)',\ title_font_size=30) fig.update_xaxes(showline=True, linewidth=2, linecolor='black') fig.update_yaxes(showline=True, linewidth=2, linecolor='black') fig.show()

我想这样打印:[a b c d a a b d c c]

我认为我应该使用 forwhile 循环,但我不知道如何使用。我已经考虑了几个小时并做了一些研究,但找不到任何有价值的东西。

5 个答案:

答案 0 :(得分:3)

给你。

#include <stdio.h>

int main(void) 
{
    char a[] = { 'a', 'b', 'c', 'd', 'a', 'a', 'b', 'd', 'c', 'c' };
    const size_t N = sizeof( a ) / sizeof( *a );
    
    for ( size_t i = 0; i < N; i++ )
    {
        size_t j = 0;
        
        while ( j != i && a[j] != a[i] ) ++j;
        
        if ( j == i ) printf( "%c ", a[i] );
    }
    
    putchar ( '\n' );
    
    return 0;
}

程序输出为

a b c d 

或者例如,如果您有一个包含字符串的字符数组,那么可以通过以下方式实现相同的方法。

#include <stdio.h>

int main(void) 
{
    char s[] = { "abcdaabdcc" };

    for (const char *p = s; *p != '\0'; ++p )
    {
        const char *prev = s;
        
        while ( prev != p && *prev != *p ) ++prev;
        
        if ( prev == p ) printf( "%c ", *p );
    }
    
    putchar ( '\n' );
    
    return 0;
}

程序输出和上图一样就是

a b c d 

答案 1 :(得分:2)

由于数组是一个包含小写字母的字符数组,因此几乎没有不同的值。因此,您可以制作一个表格(又名另一个数组)来跟踪已打印的值。

喜欢:

#define MAX ('z' - 'a' + 1)  // Calculate the number of unique elements

int already_printed[MAX] = { 0 };       // Mark all chars as "not printed"
for (i = 0; i < SIZE_OFF_ARRAY; ++i)
{
    if (already_printed[array[i] - 'a'] == 0)   // If NOT printed yet
    {
        printf("%c\n", array[i]);               // Print it and
        already_printed[array[i] - 'a'] = 1;    // mark it as printed
    }
}

这为您提供了一个简单的 O(N) 解决方案。在处理大型数组时,拥有 O(N) 解决方案对于提高性能很重要。

注意:此解决方案假设所有数组元素都在 'a''z' 之间(均包括在内),但可以轻松扩展以支持更多更广泛的范围。

答案 2 :(得分:1)

一个简单的方法:

#include <stdio.h>

int main() {

    int ascii[128] = { 0 };
    char input[] = "abcdaabdcc";
    
    for(int i = 0; input[i]; i++) {
        
        ++ascii[(int)input[i]];
    }
    
    for(int i = 0; i < 128; i++) {
        
        if( ascii[i] ) printf("%c ", i);
    }
    
    return 0;
}

数组 ascii 用于跟踪具有非负值的 128 个 ascii 字符中每个字符的频率(例如 'a' 为 97,'0' 为 48)。然后如果字符的频率不为 0,则打印该字符。

答案 3 :(得分:1)

我不确定数组中元素的类型是什么,但让我们假设它是 C 可以“本地”比较的某种类型。然后概念上简单的解决方案是对数组进行排序,并跳过重复的打印。排序将确保重复项是相邻的。这种方法在大多数情况下都会表现良好。

首先,让我们设置一些特定于元素类型的辅助函数。如果您只想处理 char 类型,您可以删除 assign 函数,但无论如何它都会被编译器内联。

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

// You can adapt the element type per your requirements
typedef char ElementType;

// This function assigns the source value to the destination:
// it does what *dst = *src would do.
static inline void assign(void *dst, const void *src)
{
    *(ElementType*)dst = *(const ElementType*)src;
}

// This is the "spaceship" comparison operator (<=> in C++) that
// merges less-than, equal, and more-than comparisons into one.
int compare(const void *l, const void *r) 
{
    const ElementType *L = l;
    const ElementType *R = r;
    if (*L < *R) return -1;
    if (*L > *R) return 1;
    return 0;
}

void print_element(const ElementType *el) { printf("%c", *el); }

既然我们计划对数组进行排序,我们需要先复制它——毕竟,数组的“打印机”不应该修改它。这样的修改在小程序中是可以的,但只是一个坏习惯,因为如果你查看像 print_unique 这样的函数名,没有任何迹象表明它会修改它应该打印的数据:这不是打印的方式通常行为。这会出乎意料,而且很容易出错。

如果可以修改源数组,则可以跳过复制操作:那么它的元素需要是非常量的,并且 print_unique 函数名称需要更改为类似 {{1} }.

sort_and_print_unique

现在是唯一的元素打印机,并使用您提供的数据进行测试:

ElementType *copy_array(const ElementType *src, const int count)
{
    ElementType *copy = malloc(sizeof(ElementType) * count);
    if (!copy) abort;
    for (int i = 0; i < count; ++i)
        assign(copy + i, src + i);
    return copy;
}

输出:void print_unique(const ElementType *data, int const count) { ElementType *copy = copy_array(data, count); qsort(copy, count, sizeof(ElementType), compare); printf("["); for (int i = 0; i < count; ++i) { if (i == 0 || compare(copy+i, copy+i-1) != 0) { if (i != 0) printf(" "); print_element(copy+i); } } printf("]\n"); } int main() { const char array[] = "abcdaabdcc"; print_unique(array, sizeof(array)/sizeof(*array) - 1); }

我上面提到的替代的、修改的实现是:

[a b c d]

答案 4 :(得分:0)

首先对数组进行排序(例如使用qsort(3)),然后将所有相等的元素放在一起。然后对数组进行一次传递,保存最后打印的元素...如果现在要打印的元素与最后打印的元素相同,只需跳过它并continue; 到下一个。

相关问题