Вычиталка строк.

Discussion in 'ПО для Web разработчика' started by -=lebed=-, 12 Dec 2009.

  1. -=lebed=-

    -=lebed=- хэшкрякер

    Joined:
    21 Jun 2006
    Messages:
    3,804
    Likes Received:
    1,960
    Reputations:
    594
    Есть 1 файл, содержащий строки, заканчивающиеся \r\n
    Есть 2 файл, содержащий строки, заканчивающиеся \r\n, являющийся подмножеством 1 файла.

    Задача: получить 3 файл, состоящий из строк 1 файла, которых нет во втором файле. Т.е. сделать вычитание одного множества из другого.

    На php писать 10-мин, отладить ещё 10. Но интересуют красивые и быстрые решения, которые будут работать быстро с файлами большого размера и не вылетать по ошибке нехватки памяти. Буду признателен, если увижу красивое и оптимальное решение поставленной задачи.
    P.S. Для упрошения решения задачи: строки - это md5 хэши в символьном виде. ;)
     
    1 person likes this.
  2. lukmus

    lukmus Elder - Старейшина

    Joined:
    18 Nov 2009
    Messages:
    402
    Likes Received:
    118
    Reputations:
    23
    на ruby писал для себя, помимо вычитание умеет еще складывать, сортировать, поднимать и опускать регистр
    Code:
    #!/usr/bin/ruby
    
    n=ARGV.size
    if n<=3 or n>5 
      puts "Not enought arguments\n <firstfile> <secondfile> <+|-> [outputfile] [-su<d|U>]"
      exit
    end
    $fi_file=ARGV[0]
    $se_file=ARGV[1]
    $sign=ARGV[2]
    if $sign!='+' and $sign!='-'
      puts "Unknow argument #{$sign}"
      exit
    end
    
    
    def make (str)
      sort=false
      udcase=0
      uniq=false
      if str.include? 's' then sort=true end
      if str.include? 'd' then udcase=1 else
        if str.include? 'U' then udcase=2 else udcase=0 end
      end
      if str.include? 'u' then uniq=true end
      return sort,udcase,uniq
    end
    
    if n>3
      if !(ARGV[3].include?('-s') or ARGV[3].include?('-d') or ARGV[3].include?('-U') or ARGV[3].include?('-u'))
        $outfile=ARGV[3]
      else
        $outfile=$fi_file+$se_file+'_out'
        $sort,$udcase,$uniq=make ARGV[3]
      end
    
      if n==5 then  $sort,$udcase,$uniq=make ARGV[4] end
    
    end
    
    
    begin
     f_arr=IO.readlines($fi_file)
    rescue => e
      puts "Can't read file #{$fi_file}:#{e}"
    end
    
    begin
     s_arr=IO.readlines($se_file)
    rescue => e
      puts "Can't read file #{$se_file}:#{e}"
    end
    
    f_arr.each {|x| x.chop!}
    s_arr.each {|x| x.chop!}
    
    case $sign
    when '-'
      r_arr=f_arr-s_arr
    when '+'
      r_arr=f_arr+s_arr
    end
    
    
    if $udcase==1 
      puts "Downcase..."
      r_arr.each {|x| x.downcase!} 
    end
    if $udcase==2
      puts "Upcase..." 
      r_arr.each {|x| x.upcase!} 
    end
    if $uniq 
      puts "Delete repetitions..."
      r_arr.uniq! 
    end
    if $sort 
      puts "Sort..."
      r_arr.sort! 
    end
    
    begin
      puts "Create output file #{$outfile}"
      File.open($outfile,"w") {|file| r_arr.each {|x| file.puts x }}
    rescue => e
      puts "Can't create file #{$outfile}:#{e}"
    end
    
    
    я думаю преобразование в cgi особого труда не составит
     
    1 person likes this.