@AprilSnow

Как правильно переписать часть кода с Python на Си?

Есть такой код:
primary_list = tuple([line.strip() for line in open('file1.txt', 'r')])
secondary_list = tuple([line.strip() for line in open('file2.txt', 'r')])
f = open('test.txt', 'w')

users_unique = []

def isUnique(value):
	if value not in users_unique:
		users_unique.append(value)
		return True
	else:
		return False

def common():
	for item in primary_list:
		if item is None:
			continue
		elif item in secondary_list and isUnique(item):
			f.write(str(item)+'\r\n')
	print 'Complete'

Стоит задача переписать его на Си. Вот мои наработки:
#include <stdio.h>
#define N 10
#include <stdbool.h>

bool isvalueinarray(char val, char arr, char size){
    int i;
    for (i=0; i < size; i++) {
        if (arr[i] == val)
            return true;
    }
    return false;
}

main () {
    FILE *primary_list;
    char arr[N];
    FILE *secondary_list;
    char arr2[N];
    FILE *f;

    primary_list = fopen("file1.txt", "r");
    secondary_list = fopen("file2.txt", "r");
    f = fopen("f.txt", "w");

    while (fgets (arr, N, primary_list) != NULL){
        fputs(arr, f);
    };
    while (fgets (arr2, N, secondary_list) != NULL){
            fputs(arr2, f);
    };

    printf("\n");
    fclose(f);
}

Что нужно поправить в функции проверки на уникальность, чтобы все работало? Подскажите, пожалуйста, куда копать. Заранее спасибо
  • Вопрос задан
  • 1235 просмотров
Решения вопроса 1
@throughtheether
human after all
primary_list = tuple([line.strip() for line in open('file1.txt', 'r')])
secondary_list = tuple([line.strip() for line in open('file2.txt', 'r')])
Квадратные скобки, на мой взгляд, необязательны.

for item in primary_list:
    if item is None:
      continue
Не уверен, что эта ветвь выполнится хотя бы раз.

Если стоит задача ускорить работу скрипта, то, на мой взгляд, проще переписать так:
primary_set = frozenset(line.strip() for line in open('file1.txt', 'r'))
secondary_set = frozenset(line.strip() for line in open('file2.txt', 'r'))
with open('test.txt', 'w') as f:
    for item in primary_set&secondary_set:
        if item:
            f.write(item+'\n')
print 'Complete'

Можете добавить сортировку по вкусу.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 4
@Dvvarreyn
Множества (set) нужно использовать и на c++, и на питоне.
Считать оба файла в множества, взять пересечение, и распечатать.
Ответ написан
Комментировать
@Eddy_Em
Если списки небольшие, можно вообще в баше выдрать уникальные записи, просто отсортировав оба и запустив comm.
Если списки большие, то я бы использовал БД, нежели самостоятельно такое выделывать.
Если же это — лабораторная работа, то а) заполняем два строковых массива считанными данными; б) сортируем их; в) пробегаемся по отсортированным данным, избегая повторов, и выдираем совпадения. Можно готовые алгоритмы поискать.
А еще есть самый тупой вариант: делаем mmap обоих файлов, строка за строкой читаем первый, при помощи strstr ищем это во втором, заполняем. В принципе, на коротких файлах даже этот способ никакого заметного торможения не выдаст.
Ответ написан
@lega
Если файлы отсортированы, то можно итерировать оба файла одновременно (с выравниванием позиции по значению), таким образом за один проход можно получить пересечение, без необходимости все загружать в память.

Если не сортированы, тогда загрузить в set'ы и выполнить пересечение, как посоветовали выше.
Ответ написан
Комментировать
@FloorZ
bool isvalueinarray(char val, char arr, char size){
    int i;
    for (i=0; i < size; i++) {
        if (arr[i] == val)
            return true;
    }
    return false;
}


Эм... что это за char size? Почему тип int сравнивается с типом char?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы