【问题标题】:Fibonacci bit string representation斐波那契位串表示
【发布时间】:2014-02-19 07:03:42
【问题描述】:

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

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

在我们的作业中,我们还需要计算字符的频率,并对它们进行排名。我已经完成了这部分,但是对将这些字符转换为斐波那契表示感到困惑(我的程序确实根据等级输出了 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 # 表示形式转换为斐波那契数列的比特串形式? 让我知道我是否可以澄清任何问题或在问题中添加信息以帮助你们充分理解我正在尝试做的事情。

【问题讨论】:

  • 如果我理解正确,您的问题是如何向后打印数字的二进制表示?
  • @Njol 不是二进制,而是一种“斐波那契”二进制表示。每个数字位置对应于 1、2、3、5、8、13 等。所以斐波那契 7 = 1010 因为 5+2 = 7。
  • 对整数 N 进行编码:找到等于或小于 N 的最大斐波那契数;从 N 中减去这个数字,记录余数。如果减去的数字是第 i 个斐波那契数 F(i),则将 1 放在代码字中的 i-2 位置(将最左边的数字计为位置 0)。重复前面的步骤,用余数代替 N,直到余数为 0。在代码字中最右边的数字后面加一个 1。
  • @MariusŽilėnas 我刚刚在维基百科上找到了这个解释。但是,我被困在这个编码方面。我确实了解该算法,只是将其转换为代码是我遇到的问题。想了一会儿,我会回到这个问题。

标签: java sorting compression sequence fibonacci


【解决方案1】:

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

基于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;
        }
    }
}

【讨论】:

  • 非常感谢!!当我使用编译器时,我会分析并尝试一下!这些 Wiki 资源的信息量惊人地丰富!
猜你喜欢
  • 2018-07-03
  • 2011-05-07
  • 2012-12-29
  • 1970-01-01
  • 1970-01-01
  • 2017-07-08
  • 1970-01-01
  • 2015-06-05
  • 2014-05-23
相关资源
最近更新 更多