powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / C++ [игнор отключен] [закрыт для гостей] / Тяпничная география
25 сообщений из 177, страница 4 из 8
Тяпничная география
    #38905358
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Приаттачу первые 10 тыс строк базы. Чтоб было на чём тренироваться.
...
Рейтинг: 0 / 0
Тяпничная география
    #38905488
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
scanf`ы готовить не умею.

Обычно так делаю
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
#include <stdio.h>
#include <string.h>

// Разбор строки CSV (строка, разделитель, массив указателей, его размер) Кавычки в кавычках не понимает
bool parse_csv_str(char* str, char delim, char **val, int val_size)
{
	for(; val_size > 0; val_size--) {
		bool quote = (*str == '"');
		if(quote) str++;
		*val++ = str;
		if(quote) {
			str = strchr(str, '"');
			if(!str) break;
			*str++ = 0;
		}
		str = strchr(str, delim);
		if(str) *str++ = 0;
		if(!str) break;
	}
	return val_size == 1 && !str; // заполнили все и строка кончилась
}

#define COLUMN_COUNT 10

void  main(){
	FILE *f = fopen("GeoIPCity.0-10000.csv", "r");
	if(f) {
		char buf[1024];
		int line = 0;
		while(fgets(buf, 1024, f)) {
			line++;
			// убираем в конце перевод строки
			char* end = buf + strlen(buf) - 1;
			while(end >= buf && (*end == 0xA || *end == 0xD)) *end-- = 0;
			char* val[COLUMN_COUNT];
			if(!parse_csv_str(buf, ',', val, COLUMN_COUNT)) {
				printf("error at line %d\n", line);
				break;
			} else {
				printf("startIpNum = '%s'\n", val[0]);
				printf("endIpNum = '%s'\n", val[1]);
				printf("country = '%s'\n", val[2]);
				printf("region = '%s'\n", val[3]);
				printf("city = '%s'\n", val[4]);
				printf("postalCode = '%s'\n", val[5]);
				printf("latitude = '%s'\n", val[6]);
				printf("longitude = '%s'\n", val[7]);
				printf("dmaCode = '%s'\n", val[8]);
				printf("areaCode = '%s'\n", val[9]);
				printf("---------------------\n");
			}
		}
		fclose(f);
	}
}

...
Рейтинг: 0 / 0
Тяпничная география
    #38905508
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Марк, что нужно с запятыми и scanf, приведите пример пожалуйста для особо одарённых :D
...
Рейтинг: 0 / 0
Тяпничная география
    #38905514
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonЗначит вот что я придумал.

Итак 239 стран. Надо раздать им цвета.

Палитру белых-серых-черных я резервирую для системных нужд.

Поэтому цвета близкие к FFFFFF, C0C0C0, 000000 будут игнорироваться при маппинге.

Top 6 стран должны получить наиболее яркие цвета.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
Code  Allocation Color
----- ---------- ------
US    1507673738 'red'
CN     267741269 'green'
JP     186372005 'blue'
GB     115678470 'magenta'
DE     111001300 'yellow'
KR      99794924 'cyan'



Поэтому вышеуказанные цвета будут удалены из оставшихся. Будут также удалены все "близкие" к ним цвета.
По формуле цветового расстояния RGB. С учётом весов.

Итак 239 - 6 = 233

Далее у нас есть две палитры. Pantone, HtmlColors. Грубо говоря 121 + 120 (Я удалил градации серых и белых).

Это 241 Цвет. Нужно еще что-то выкинуть.

Полагаю в двух палитрах будут цвета дубликаты. Или "близкие" цвета.

Буду удалять их до тех пор пока не останется 233.

А как будет происходить работа с остальными странами ? Вдруг у двух близлежащих стран будут схожие цвета
...
Рейтинг: 0 / 0
Тяпничная география
    #38905521
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryчто нужно с запятыми и scanf
Разобрать строку с разделителем запятая на отдельные строки
Например
Код: plaintext
1.
1.0.0.0,1.7.255.255,"AU","","","",-27.0000,133.0000,,


Файлик со строками выше.
...
Рейтинг: 0 / 0
Тяпничная география
    #38905534
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да вот мне miksoft посоветовал fscanf. И я "ринулся".... И как-то оно так вышло.
...
Рейтинг: 0 / 0
Тяпничная география
    #38905546
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryА как будет происходить работа с остальными странами ? Вдруг у двух близлежащих стран будут схожие цвета
В данной таблице я просто привёл распределение адресов по странам. В реальности (смотри сsv файл)
страны идут в случайном порядке.

Как быть с очень близкими цветами - я не знаю. Есть варианты.

1) Раскрашивать страну в один из четырёх цветов полагаясь на теорему о четырех
красках.

https://ru.wikipedia.org/wiki/Проблема_четырёх_красок

Это в случае использования кривой Гилберта которая должна дать для каждого диапазона
цельную геометрическую фигуру (квадрат, прямоугольних или множество соприкасающихся
квадратов разного размера).

Для Z-кривой к сожалению непрерывность областей не обеспечивается.

2) Красить по первому варианту. Самые популярные страны - в системные цвета. А оставшиеся
в mapped-порядке брать из таблицы Panton, HTMLColors e.t.c.

3) Красить в произвольный цвет но на границе областей проводить жирную чёрную линию в 1pix
толщиной. Последняя задача - аналог фильтра photoshop по выделению границ. И ее можно
решать отдельно от общей задачи.
...
Рейтинг: 0 / 0
Тяпничная география
    #38905564
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonДа вот мне miksoft посоветовал fscanf. И я "ринулся".... И как-то оно так вышло.

Тут не должно быть проблем, меня скоро выгонят из этого компьютера, но я попробую успеть
...
Рейтинг: 0 / 0
Тяпничная география
    #38905568
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Давай дерзай. Я свой лимит времени на fscanf потратил. Займусь пока чем-то другим
полезным. К сканфу вернусь чуть позже.
...
Рейтинг: 0 / 0
Тяпничная география
    #38905586
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пока так, где-то ошибся, вечером ещё посмотрю

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
FILE* in = fopen("Mayton.txt", "r");
	char startIP[20] = "\0", endIP[20] = "\0";
	char country[30] = "\0", region[30] = "\0", city[30] = "\0", postalCode[30] = "\0";
	char latitude[10] = "\0", longitude[10] = "\0";
	char dmaCode[10] = "\0", areaCode[10] = "\0";
	char t;
	for (int i = 0; i < 10; ++i)
	{
		fscanf(in, "%[^,],%[^,],%c%[A-Z]%c,%c%[A-Z]%c,%c%[A-Z]%c,%c%[A-Z]%c,%[^,],%[^,],%[^,],%[^\n]", 
			       startIP,  
				   endIP, 
				   &t, country, &t,//в t читаю двойные кавычки
				   &t, region, &t, 
				   &t, city, &t,
				   &t, postalCode, &t, 
				   latitude, 
				   longitude, 
				   dmaCode, 
				   areaCode);
		printf("%s %s %s %s %s %s %s %s %s %s\n",
			startIP,
			endIP,
			country,
			region, 
			city,
			postalCode, 
			latitude,
			longitude,
			dmaCode,
			areaCode);
		//сделать указатели всех строк на "\0" !
	}

...
Рейтинг: 0 / 0
Тяпничная география
    #38905701
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ОК. Попробую вечером.

Если чесно то вариант Димы мне больше нравится. Если взлетит - то возьму его.
...
Рейтинг: 0 / 0
Тяпничная география
    #38905723
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonЕсли взлетит - то возьму его.
Не взлетит - пиши на чем споткнется, поправлю. Пока там проигнорирован один момент стандартного CSV: если значение содержало кавычки, то они превращаются в две двойные кавычки, т.е. ООО "АБВ" запишется как "ООО ""АБВ""". У тебя вроде не должно такого быть. С ходу не придумал как по простому это обработать, вечером время будет, еще подумаю как это полечить.
...
Рейтинг: 0 / 0
Тяпничная география
    #38905734
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Конечный автомат-парсер спасёт отца русской демократии меня, но вот какова будет цена
вопроса на pure "C" . Выше я задумался о Golang/Python/Rust/D для решения данной узкой задачи. Но
коллеги-сишники меня закидают помидорами.
...
Рейтинг: 0 / 0
Тяпничная география
    #38905783
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

только сейчас подумалось - зачем парсить вручную, если Оракл сам умеет СSV грузить как минимум двумя способами - через external tables и через SQL*Loader ?
...
Рейтинг: 0 / 0
Тяпничная география
    #38905793
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я делаю софт без привязки к Oracle. БД я использовал просто чтобы посмотреть
кое-какие срезы по странам и мини-максные характеристики.

Кстати вопрос перекрытия диапазонов остался открытым. Я знаю как его решать
алгоритмически но не знаю как он решается в SQL.

Подниму-ка топик.
...
Рейтинг: 0 / 0
Тяпничная география
    #38905805
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хотя.... зачем. Щас попробую.
...
Рейтинг: 0 / 0
Тяпничная география
    #38905838
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonне знаю как он решается в SQL.если адреса перевести в числа, то элементарно.
...
Рейтинг: 0 / 0
Тяпничная география
    #38905867
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonКонечный автомат-парсер
Чего это я сразу про него не вспомнил, с ним проще.

Держи версию 2.0
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
#include <stdio.h>

int parse_csv_str(char* str, char **val, int val_size)
{
	int val_count = 0;
	bool quote_open = false;
	bool first = true;
	bool end_quote = false;
	bool center_quote = false;
	bool stop = false;
	while(!stop) {
		if(first) {
			first = false;
			if(val_count < val_size) *val = str;
			val_count++;
		}
		switch(*str) {
			case '"':
				quote_open = !quote_open;
				if(*val == str) {
					(*val)++; // пропуск кавычки в начале
					end_quote = true;
				} else {
					center_quote = true;
				}
				break;

			case ',':
				if(!quote_open) {
					*str = 0;
					first = true;
					if(end_quote) { // пропуск завершающей кавычки
						end_quote = false;
						*(str - 1) = 0;
					}
					if(center_quote) { // удаление двойных кавычек в центре
						center_quote = false;
						char* d = *val;
						char* s = *val;
						while(*d = *s) {
							if(*s != '"' || *(s + 1) != '"') d++;
							s++;
						}
					}
					if(val_count < val_size) val++;
				}
				break;

			case 0:
				stop = true;
				break;

			case 0xD:
			case 0xA:
				*str = 0;
				stop = true;
				break;

		}
		str++;
	}
	// заполнение пустыми строками недостающих
	for(int i = val_count; i < val_size; i++) *(++val) = str;
	// возврат количества параметров
	return val_count;
}

void  main(){
	FILE *f = fopen("GeoIPCity.0-10000.csv", "r");
	if(f) {
		char buf[1024];
		int line = 0;
		while(fgets(buf, 1024, f)) {
			line++;
			if(line == 1) {
				int cnt = parse_csv_str(buf, NULL, 0);
				printf("%d parameters at line\n---------------------\n", cnt);
				continue;
			}
			char* val[10];
			int cnt = parse_csv_str(buf, val, 10);
			printf("startIpNum = '%s'\n", val[0]);
			printf("endIpNum = '%s'\n", val[1]);
			printf("country = '%s'\n", val[2]);
			printf("region = '%s'\n", val[3]);
			printf("city = '%s'\n", val[4]);
			printf("postalCode = '%s'\n", val[5]);
			printf("latitude = '%s'\n", val[6]);
			printf("longitude = '%s'\n", val[7]);
			printf("dmaCode = '%s'\n", val[8]);
			printf("areaCode = '%s'\n", val[9]);
			printf("---------------------\n");
			if(cnt != 10) {
				printf("error: %d parameters at line %d\n", cnt, line);
				break;
			}
		}
		fclose(f);
	}
}


Первая корявая получилась. Хотел допилить кавычки и в свою библиотеку прибрать, пригодится, потом подумал обычно надо еще знать сколько всего колонок прежде чем парсить. Получилось проще новую написать :)

Твой файлик проходит без ошибок.
...
Рейтинг: 0 / 0
Тяпничная география
    #38905869
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я понял. Мой моск лихорадочно ищет оптимизаций. Задача решается в биткарте или
в любой структуре которая учитывает флаги.

Решая эту задачу реляционно я вынужден делать соединение таблицы самой с собой.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
select 
    count(*) 
from 
    geoipcity g1,geoipcity g2
where
  ..... // здесь будет несколько предикатов которые проверяют различные варианты 
  // перекрытия отрезков N_STARTIP1...N_ENDID1, N_STARTIP2...N_ENDID2



Грубо... для оптимизатора без использования индекса это будет

5748952 * 5748952 = 33 050 449 098 304 или 33 триллиона сравнений.

Вот так вот.

P.S. 33 коровы.... Ну что. В топике есть SQL-щики оптимизаторы?
...
Рейтинг: 0 / 0
Тяпничная география
    #38905881
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Или.... если-бы таблица была сегментирована к примеру по N_STARTIP то тогда
возможно Oracle optimizer сделал-бы не квадрат количества rows а "треугольник"
или "квадратичную" оценку с весовым коэффициентиком меньше единицы.
...
Рейтинг: 0 / 0
Тяпничная география
    #38905886
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonВ топике есть SQL-щики оптимизаторы?Показывайте DDL таблицы
...
Рейтинг: 0 / 0
Тяпничная география
    #38905888
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
17382368

Всё в силе. Только "virtual" уберите.
...
Рейтинг: 0 / 0
Тяпничная география
    #38905893
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftmaytonВ топике есть SQL-щики оптимизаторы?Показывайте DDL таблицы
лучше с тестовыми данными, типа такого
Код: plaintext
1.
2.
3.
4.
create table XXX (...)
insert into xxx values (...)
insert into xxx values (...)
...


тут похожая тема была, только с перекрытием квадратов http://www.sql.ru/forum/1120376-1/karty
...
Рейтинг: 0 / 0
Тяпничная география
    #38905900
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я помню эту тему.
...
Рейтинг: 0 / 0
Тяпничная география
    #38905916
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Делаешь таблицу points(nIP) и туда пишешь каждый IP из каждого диапазона. Будет около 4 млрд. записей.

Затем
Код: plaintext
1.
select nIP, count(*) as nCnt from points group by nIP having nCnt > 1


:)
...
Рейтинг: 0 / 0
25 сообщений из 177, страница 4 из 8
Форумы / C++ [игнор отключен] [закрыт для гостей] / Тяпничная география
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]