Avatar billede figora Nybegynder
19. oktober 2009 - 21:48 Der er 9 kommentarer

Læse sekvens fra fil, for derefter at slå en værdi op i en anden

Jeg har forsøgt at skrive en del af et program, som har den funktion at den læser en fil, som den så deler op i mindre bider af tre bogstaver. Hver af disse bider, på tre bogstaver, bliver så slået op i en anden fil, som giver den bid en værdi.

Jeg forestiller mig at sådan en funktion læser de tre første bogstaver, slår den op i en anden fil, skirver værdien ind i en array, og forsætter med de næste tre bogstaver i rækken.

Jeg har prøvet mig lidt frem, men får problemer når jeg skal sammenligne et stykke med en sekvens, samt har jeg ingen idé om hvordan man slår sådan en bid op.

Håber nogen vil hjælpe mig igennem dette.
Avatar billede bertelbrander Novice
19. oktober 2009 - 22:45 #1
Der er flere ubekendte i din beskrivelse, men lad os tage det fra en ende af.

At læse tre bogstaver fra den ene fil bør ikke volde problemer. Brug en std::ifstream og dens get metode til at læse med.

Det næste er så at "slå op" i den anden fil.
Det kan man gøre ved at læse en "record" af gangen og sammenligne med de tre bogstaver. En record er i dette tilfælde en kombination af tre bogstaver og den associerede værdi. Det er igen forholdsvis enkelt, men kan tage lidt lang tid.

Du kan også læse den anden fil én gang for alle og gemme det hele i en container. Her vil en std::map være på sin plads.

Hvis du fortæller hvordan de to filer ser ud, og hvordan definitionen af "værdien" ser ud, kan jeg komme med et mere kvalificeret svar.
Avatar billede bauerdata Nybegynder
20. oktober 2009 - 11:47 #2
Pseudo kode som skitserer en løsning

#!/usr/bin/env python
#
# hvis test er True genereres en lookup.txt fil pga en tæller og input fra key.txt
test = not True

# key.txt indholder
# adbasdkymlknsadlykjmlnasmdfasdfepyasypdmfy

# læs nøglerne ind og split dem op i længder af 3.
text = open("keys.txt")
text = text.read()
keys = [text[x:x + 3] for x in range(0, len(text)-1, 3)]

# generer test data
# filformat
# adb, 0
# asd, 1
# kym, 2
# ...
if test:
    text =  open("lookup.txt","w")
    for ix, key in enumerate(keys):
        text.write("%s, %s\n" % (key, ix))
    text.close()

# læs lookupfil ind i et dictionary med navnet lookup
text =  open("lookup.txt","r")
lookup = {}
x = text.readline().strip()
while x:
    key,val = x.split(",")
    lookup[key] = val
    x = text.readline().strip()

# udskriv koderne ved opslag i lookup
for key in keys:
    print lookup.get(key, "Notfound %s" % key)
Avatar billede figora Nybegynder
20. oktober 2009 - 17:20 #3
Den første fil, som den skal læse fra, indeholder en masse bogstaver som fx "AAACCCGTTGCT..." Det den så gør er at slå AAA op og give den en tal (int) værdi, gå videre til CCC og give den en anden talværdi. og det forsætter den så med. Den anden fil ved jeg ikke helt hvordan jeg skal udforme, da den bare indeholder sekvenser af tre bogstaver som har hvert deres talværdi.

Jeg skiver i C++.
Avatar billede bertelbrander Novice
20. oktober 2009 - 20:54 #4
En måde at gøre det på:
#include <iostream>
#include <fstream>
std::string GetTreeLetters(std::ifstream& in)
{
  std::string ret;
  char ch = in.get();
  ret = ch;
  ch = in.get();
  ret += ch;
  ch = in.get();
  ret += ch;
  if(in.eof())
      return "";
  return ret;
}

int main()
{
  std::ifstream in1("test1.dat");
  std::string treeLetters;
  while((treeLetters = GetTreeLetters(in1)) != "")
  {
      std::ifstream in2("test2.dat");
      std::string temp;
      int n;
      while(in2 >> temp && in2 >> n && temp != treeLetters)
      {
        /* Just looping */
      }
      if(temp == treeLetters)
        std::cout << "Match: " << treeLetters << " " << n << std::endl;
      else
        std::cout << "NoMatch" << std::endl;
  }
}


Jeg brugte disse to filer til at teste med:
test1.dat:
abcdefghi

test2.dat:
abc 123
ghi 321

Det giver dette resultat:
Match: abc 123
NoMatch
Match: ghi 321
Avatar billede bauerdata Nybegynder
21. oktober 2009 - 01:15 #5
skal programmet loope uendeligt hvis indata filen ikke findes ?
Avatar billede bertelbrander Novice
21. oktober 2009 - 01:36 #6
Programmet kan godt bruge lidt fejlcheck her og der.
Avatar billede arne_v Ekspert
21. oktober 2009 - 02:33 #7
Jeg ville også omdøbe nogle af navnene - træ bogstaver er sådan et mystisk begreb.

:-)
Avatar billede figora Nybegynder
13. november 2009 - 14:04 #8
Mange tak for hjælpen, har bare det lille problem at den ikke tåler decimal tal (xx.xxx), hvad skal det til for at afhjælpe det?
Avatar billede figora Nybegynder
13. november 2009 - 14:13 #9
Anyway, problem løst. Vil du ligge et svar?
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester