Тема: Обробка файлу PHP & Python & Ruby & С++ & Java та багато інших
Вирішив створити тему під кожну задачу. Можливо в майбутньому ці теми адмін перенесе у одну гілку і все буде красиво. Поки що пропоную наступний принцип:
1. Пишемо умову задачі.
2. Пишемо розв'язок на 1ній з мов.
3. Обговорюємо.
4. Чекаємо коли користувачі напишуть на інших мовах варіант розв'язання задачі і додаємо його в головне повідомлення теми.
5. В головному повідомлені теми ставимо посилання на зв'язані теми.
Задача:
Є файл з описом будинків. Потрібно його прочитати і вивести назву вулиці і назву будинку окремо. Тобто дані мають бути структуровані. Дані розбиті табуляцією. Якщо в рядку більше 1ї табуляції (табуляції у кінці і спочатку не враховуємо) він не підходить, значить пропускаємо його. В даній задачі стараємось показати простоту мови і її синтаксис.
вул. Сергія Єфремова 1/2
вул. 100-Р.Червоного Хреста 1
вул. 100-Р.Червоного Хреста 2
вул. 100-Р.Червоного Хреста 3
вул. 100-Р.Червоного Хреста 2в
вул. 2000-Ліття Різдва Христового 4
вул. 24 Серпня 1
Задачу придумав bunyk, я трохи перефразував
Реалізація на PHP:
<?php
# author @funivan
$data = file_get_contents('buildings.txt'); # зчитуємо файл
$lines = explode(PHP_EOL, $data); # розбиваємо файл по закінченню рядка
foreach ($lines as $line) {
$houseInfo = explode("\t", trim($line)); # розбиваємо рядок по табах
if (count($houseInfo) == 2) {
# фільтруємо і виводимо дані
echo "Street: " . $houseInfo[0] . "\nHouse : " . $houseInfo[1] . "\n\n";
}
}
Результат:
Реалізація на Python:
# author @bunyk
with open('buildings.txt') as f:
for line in f:
split = line.strip().split('\t') # Викинути зайве по краях і розділити через табуляцію.
if len(split) == 2: # деякі рядки містять помилки
building, street = split
print(building, street)
Результат:
Реалізація на Ruby:
IO.foreach "t.html" do |line|
lines = line.strip.split("\t")
puts (lines.size == 2) ? "Street: #{line[0]}\nHouse: #{line[1]}\n\n" : ""
end
Реалізація на C++:
#include <string>
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
void showFile(const char* /*file*/);
int main(int argc, char* argv[]) {
if(argc>2)
showFile(argv[1]);
return 0;
}
#define trim(s) { while(s[0]=='\t') s=s.substr(1); \
while(s[s.length()-1]=='\t') s=s.substr(0,s.length()-1);}
void showFile(const char* file) {
ifstream f(file);
string content( (std::istreambuf_iterator<char>(f)), (std::istreambuf_iterator<char>()) ),
line, token;
f.close();
istringstream fileStream(content);
vector<string> rowTokens;
while(getline(fileStream,line)) {
trim(line);
istringstream stream(line);
while(getline(stream,token, '\t'))
rowTokens.push_back(token);
if(rowTokens.size() == 2) /*validation rule*/
cout<<rowTokens[0].c_str()<<" ---> "<<rowTokens[1].c_str()<<endl;
rowTokens.clear();
}
}
Результат:
Реалізація на JAVA:
public class ParseFile {
public static void main(String[] args) {
try (java.util.Scanner scanner = new java.util.Scanner(new java.io.File(args[0]))) {
while (scanner.hasNextLine()) {
String[] str = scanner.nextLine().replaceAll("^\t+|\t$+", "").split("\t");
if (str.length == 2) {
System.out.printf("%s ---> %s\n", str[0], str[1]);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Результат:
Реалізація на C#:
using System;
using System.IO;
public class HelloWorld {
static public void Main () {
try {
using (StreamReader reader = new StreamReader("t.html")) {
String line;
while ((line = reader.ReadLine()) != null) {
String[] items = line.Trim().Split(new Char[] {'\t'});
if (items.Length == 2) {
Console.WriteLine("Street: " + items[0]);
Console.WriteLine("House: " + items[1]);
Console.WriteLine();
}
}
}
}
catch (Exception e) {
Console.WriteLine(e.Message);
}
}
}
Результат:
Реалізація на BASH:
#!/bin/bash
mIFS="$IFS"
IFS=$'\n'
while read line
do
str=$line
str="${str#"${str%%[![:space:]]*}"}" #//не зовсім, але ...
str="${str%"${str##*[![:space:]]}"}" #//не зовсім, але ...
IFS=`/bin/echo -ne "\t"` read -a array <<< "$str"
if [ ${#array[*]} -eq 2 ]
then
printf '%s ---> %s ' "${array[0]}" "${array[1]}"; printf '\n'
fi
done <$1|iconv -f CP1251 -t UTF-8
IFS="$mIFS"
Результат роботи
Реалізація на SQL+Postgresql:
> psql -a -t -d postgres -p 5432 -h 127.0.0.1 -c "\
select str[1]||' ---> '||str[2]
from (select string_to_array( regexp_replace(line, '(^[\s\t\n\r]+|[\s\t\n\r]+$)', '', 'g'), e'\t') as str\
from unnest(string_to_array(convert_from(pg_read_binary_file('./01.txt'), 'win1251'), e'\n')) as foo (line)) foo\
where array_length(str, 1) = 2"
Результат:
Реалізація на PLPGSQL+Postgresql
DO $$
DECLARE
loidTxt oid;
lfdTxt integer;
fileTxt bytea;
sizeTxt integer;
line record;
rec record;
BEGIN
loidTxt := lo_import('./01.txt');
lfdTxt := lo_open(loidTxt, X'20000'::int);
sizeTxt := lo_lseek(lfdTxt,0,2);
perform lo_lseek(lfdTxt,0,0);
fileTxt := loread(lfdTxt,sizeTxt);
--raise NOTICE '%', convert_from(filetxt, 'win1251');
for line in SELECT UNNEST(string_to_array(convert_from(filetxt, 'win1251'), E'\n')) AS l
LOOP
for rec in select string_to_array( regexp_replace(line.l, '(^[\s\t\n\r]+|[\s\t\n\r]+$)', '', 'g'), E'\t') AS str
LOOP
IF array_length(rec.str,1)=2
THEN
raise NOTICE '% ---> %', rec.str[1], rec.str[2];
END IF;
END LOOP;
END LOOP;
perform lo_close(lfdTxt);
perform lo_unlink(loidTxt);
END $$;
Результат
З чого все починалось:
http://replace.org.ua/topic/995/