斐波纳契位串表示

时间:2014-01-28 05:48:45

标签: java sorting compression sequence fibonacci

我正在编写一个字符的Fibonacci表示,它接受一个输入的字符串,并根据每个字母出现的频率输出字符串的位串形式(因此。例如,如果有一种类型: “卡内基梅隆” 然后输出将是:

标题/ 01011/1011/000011/011/11 / 100011/00011/11/001011/010011 / 11/ 0011/ 0011/10011/111

在我们的任务中,我们还需要计算字符的频率,并对它们进行排名。我已经完成了这一部分,但我很困惑将这些char转换为斐波那契表示(我的程序确实按照等级输出了fib序列)。

如果有人对比特串表示的含义感到困惑,这里有一个简单的例子:

2,7,4,3,因为f(n)等于10,1010,101,100 我的老师要我们给每个人加1,然后等于011,01011,1011,0011

这是我的代码:

  import java.io.*;
import java.util.*;
import java.util.Map.Entry;
public class Freq
{
    public static void main(String args[])throws IOException
    {
        //read input stream
         BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
            System.out.println("Enter your String");
            String line = in.readLine();
            HashMap<Character,Integer> counts = new HashMap<>();
            for(char c : line.toCharArray()) {                  //cycle through char array
                Integer count = counts.get(c);                  
                if (count == null) {
                    count = 0;
                }
                counts.put(c, ++count);                         //count increments and places into map
            }
            List<Entry<Character,Integer>> list = new ArrayList<>(counts.entrySet());
            Collections.sort(list, new Comparator<Entry<Character,Integer>>() {
                //@Override
                public int compare(Entry<Character, Integer> o1,
                        Entry<Character, Integer> o2) {
                    return o2.getValue() - o1.getValue();
                }
            });
            for(Entry<Character,Integer> entry : list) {
                System.out.println("The character "+entry.getKey() +" has occured for "+ entry.getValue()+" times");
            }

            int index = 0;                          //fibanocci base case
            for(Entry<Character,Integer> entry2 : list){
                System.out.println(fibonacci(index));
                index++;
            }
    }
    public static long fibonacci(int i){
        if(i == 0){
            return 0;       //base case
        }
        if(i <= 2){
            return 1;       //base case
        }
        long fibTerm = fibonacci( i -1) + fibonacci(i-2);
        return fibTerm;
    }
}

示例输出:

Enter your String
this is a string
The character   has occured for 3 times
The character s has occured for 3 times
The character i has occured for 3 times
The character t has occured for 2 times
The character g has occured for 1 times
The character r has occured for 1 times
The character a has occured for 1 times
The character n has occured for 1 times
The character h has occured for 1 times
0
1
1
2
3
5
8
13
21

如何将我的计算的fib#表示形式转换为斐波纳契序列的这种位串形式? 如果我能清除任何内容或在问题中添加信息以帮助您完全理解我想要做的事情,请告诉我。

1 个答案:

答案 0 :(得分:0)

我在代码中添加了一些功能:

基于http://en.wikipedia.org/wiki/Fibonacci_codinghttp://en.wikipedia.org/wiki/Fibonacci_number

import java.io.*;
import java.util.*;
import java.util.Map.Entry;

public class Freq {
    public static void main(String args[]) 
        throws IOException {

        /* read input stream */
        BufferedReader in = new BufferedReader(
                new InputStreamReader(
                    System.in));

        /* System.out.println("Enter your String"); */
        String line = "carnegie mellon"; //in.readLine();

        Map<Character,Integer> counts = new HashMap<Character, Integer>();

        int ci = 0;
        for(char c : line.toCharArray()) { /* cycle through char array */
            ci = counts.containsKey(c)
                ? counts.get(c) + 1
                : 1;
            counts.put(c, ci);  /* count increments and places into map */
        }

        List<Entry<Character,Integer>> list = new ArrayList<>(
                counts.entrySet());
        Collections.sort(list, new Comparator<Entry<Character,Integer>>() {
            @Override
            public int compare(Entry<Character, Integer> o1,
                    Entry<Character, Integer> o2) {
                return o2.getValue() - o1.getValue();
            }
        });

        Map<Character, Integer> sorted = new HashMap<Character, Integer>();
        int i = 1;
        for (Entry<Character,Integer> entry : list) {
            System.out.println(
                    "The character "      + entry.getKey() 
                    + " has occured for " + entry.getValue() 
                    + " times");
            /** count occurencies of character */
            sorted.put(
                    entry.getKey(), i++);
        }


        System.out.print("Header / ");
        for (String s : encode(line, sorted)) {
            System.out.print(s + " / ");
        }
    }

    /**
     * Encode a given string.
     */
    public static List<String> encode(
            String text, Map<Character, Integer> counts) {
        List<String> encoded = new ArrayList<String>();
        for (char c : text.toCharArray()) { 
            encoded.add(
                    bitSetAsString(
                        numberToBits(
                            counts.get(c))));
        }
        return encoded;
    }

    /** 
     * Convert number to bits
     */
    public static BitSet numberToBits(long n) {
        /** next Fibonacci */
        long nextf = 0;
        int  i     = 0;
        /** remainder */
        long rem   = n;
        /** 
         * Fibonacci numbers that encode the given n.
         */
        List<Integer> fibs = new ArrayList<Integer>();

        /** temporary Fibonacci number */
        long tf    ;
        /** index of Fibonacci number */
        int  fi    ;

        do {
            /** Find largest Fibonacci smaller than rem. */
            i     = 2;
            fi    = i;
            tf    = Fibonacci.fibonacci(i);
            nextf = tf; 
            while (tf < rem) {
                tf = Fibonacci.fibonacci(i+1);
                if (tf > rem) {
                    break;
                } else {
                    nextf = tf;
                    fi    = i+1;
                }
                i++;
            }

            rem = rem - nextf;
            /** If found Fibonacci number collect it. */
            if (Fibonacci.isFibonacci(nextf)) {
                fibs.add(fi);
            }
        } while (rem > 0);

        /** make a bitset represenation */
        BitSet encoded = new BitSet();
        for(Integer j : fibs) {
            encoded.set(j-2);
        }
        /** place an additional 1 after the rightmost digit in the code */
        encoded.set(
                encoded.length());

        return encoded;
    }

    public static String bitSetAsString(BitSet bs) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bs.length(); i++) {
            sb.append(
                    bs.get(i) 
                    ? '1'
                    : '0');
        }
        return sb.toString();
    }


    static class Fibonacci {
        public static long fibonacci(long i){
            return (0 == i || 1 == i)
                    ? i 
                    : (fibonacci(i-1) + fibonacci(i-2));
        }

        public static boolean isFibonacci(long n) {
            long i     = 0;
            long nextf = fibonacci(i);
            while (nextf < n) {
                nextf = fibonacci(++i);
            }
            return nextf == n;
        }
    }
}