首页 > 解决方案 > 除以整数 HashMap 值产生零

问题描述

编辑2:通过建议后,我有两种可能的计算方法。1:

    public int percent(String token) {
        if(token != "" && token != "\n" && token != " " && map.get(token) != null) {
            double ag = 0;
            
            for (int x : map.values()) {
                ag += x;
            }
            
            int retval = (int) (((double)map.get(token)) / ag); //mapsize only shows number of unique words; change to ALL words
            return retval;
        } else {
            return 404;
        }
    } //*/

2:

    public int percent(String token) {
        if(token != "" && token != "\n" && token != " " && map.get(token) != null) {
            double ag = 0;
            
            for (int x : map.values()) {
                ag += x;
            }
            
            int retval = (int) (((double)map.get(token)) / wordCount); //mapsize only shows number of unique words; change to ALL words
            return retval;
        } else {
            return 404;
        }
    } //*/

最后的 wordCount 是一个类属性,每次构造函数添加一个值时,我都会将其加一。

旧编辑:好的,所以我已经解决了安迪在评论中指出的逻辑问题。我写的新方法是这样的:

    public int percent(String token) {
            if(token != "" && token != "\n" && token != " " && map.get(token) != null) {
                int ag = 0;
            
                for (String x : map.keySet()) {
                    ag += map.get(x);
                }
            
                int retval = map.get(token)/ag;
                return retval;
            } else {
                return 404;
       }
        
    } //*/

但是,我在 Driver 中的测试仍然得到 0 的输出。我还冒昧地更改了 test.txt 及其下面的输出。

原帖:

我目前正在做一个项目,我必须从文件中获取输入并使用 HashMap 来计算每个单词的频率。我们必须为“freqCount”类创建一些必需的方法,其中之一是public int percent(String token),它接受一个字符串并尝试查找原始文件中有多少与它匹配。我认为最简单的方法是将已经计算的字符串频率除以 HashMap 的大小。当我执行时,它每次都返回零。

在这里和那里进行更改并获得结果后,我发现/是导致值变为 0. +-,并且*工作正常的原因。

从这里我假设它是整数类型将小数四舍五入为零,但即使将函数更改为浮点数或双精度数,它仍然会打印 0.0。

司机:

package fint;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.util.ArrayList;

public class Driver {
    
    public static void main(String[] args) throws FileNotFoundException{
        //---------------CONSTANTS---------------
        final String PERC_STRING = "the"; //set these to whatever you want for testing purposes
        final String COUNT_STRING = "the";
        
        //---------------------------------------
        
        File in = new File("test.txt");
        Scanner scanFile = new Scanner(in);
        
        ArrayList<String> parsed = new ArrayList<String>();
        
        
        while(scanFile.hasNext()) { 
            parsed.add(scanFile.next().toLowerCase());
        }
        
        for(int i = parsed.size()-1; i>=0; i--) { //prints arraylist backwards
            System.out.println(parsed.get(i));
        } //*/
        
        FreqCount fc = new FreqCount(parsed);
        //----------------------------------------------------------------------------------------------
        
        //percent() test
        System.out.println("\nTest word '" + PERC_STRING +"' percentage: " + fc.percent(PERC_STRING));
        
        //count() test
        System.out.println("\nCount of '" + COUNT_STRING + "': " + fc.count(COUNT_STRING));
        
        //printMap() test
        System.out.println("\nHashmap: \n");
        fc.printMap();
        
        scanFile.close();

    }
}

频率计数:

package fint;

import java.util.HashMap;
import java.util.List;
import java.lang.Math;

public class FreqCount {
    //attributes----------------------------------------------------------------------------------------
    
    private HashMap<String, Integer> map = new HashMap<String, Integer>();
    
    //constructors--------------------------------------------------------------------------------------
    
    FreqCount(List<String> driverList) {
        for (int dLIndex = driverList.size() - 1; dLIndex >= 0; dLIndex--) {
            String key = driverList.get(dLIndex);
            if (map.get(key) == null) {
                map.put(key, 1);
            } else {
                map.put(key, map.get(key) + 1);
            }
        }
    }
    
    /*FreqCount(List<String> driverList, int degree){ //will specify number (degree) of words in a token (" hello world " would one token of degree 2)
        
    } //*/
    
    
    
    //methods (required)---------------------------------------------------------------------------------
    
    public int count(String token) { //returns value of a key
        if(token != "" || token != "\n" || token != " ") {
            return map.get(token);
        } else {
            return 0;
        }
    } //*/
    

//THIS METHOD v v v v v v v v

    public int percent(String token) {
        if(token != "" && token != "\n" && token != " " && map.get(token) != 0) {
            int retval = map.get(token)/map.size(); //problem area
            return retval;
        } else {
            return 404; //404 isn't special, just random code i chose for debug purposes
        }
        
    } //*/



    
    //testing methods (not required)---------------------------------------------------------------------
    
    public void printMap() {
        for (String i : map.keySet()) { //loop ripped straight outta w3schools lol
              System.out.println("key: " + i + " value: " + map.get(i));
        }
    } //*/

}

文字输入:

There were a number of factors that came together to contribute to the adaptive radiation of monkeys and decreased diversity of apes. The first involves the rifting of the African Plate somewhere between 60 and 10 million years ago. These plates split into what are known today as the Nubian plate and the Somali plate. This split happened alongside volcanic activity creating localized and varied environments. The different environments and food sources forced the populations of primates living in each to evolve through natural selection. The rift of the African plate combined with the phenomenon of continental drift caused the continents of Africa and Eurasia to be reconnected over time.

输出(百分比测试大约在中途):


Hashmap: 

key: through value: 1
key: environments value: 1
key: forced value: 1
key: somewhere value: 1
key: years value: 1
key: these value: 1
key: that value: 1
key: number value: 1
key: split value: 2
key: time. value: 1
key: different value: 1
key: between value: 1
key: drift value: 1
key: 10 value: 1
key: africa value: 1
key: primates value: 1
key: plates value: 1
key: natural value: 1
key: in value: 1
key: involves value: 1
key: this value: 1
key: nubian value: 1
key: varied value: 1
key: continents value: 1
key: each value: 1
key: monkeys value: 1
key: as value: 1
key: environments. value: 1
key: million value: 1
key: were value: 1
key: creating value: 1
key: 60 value: 1
key: apes. value: 1
key: populations value: 1
key: continental value: 1
key: be value: 1
key: sources value: 1
key: activity value: 1
key: localized value: 1
key: contribute value: 1
key: plate value: 3
key: phenomenon value: 1
key: into value: 1
key: adaptive value: 1
key: diversity value: 1
key: known value: 1
key: are value: 1
key: and value: 6
key: of value: 8
key: today value: 1
key: came value: 1
key: together value: 1
key: over value: 1
key: somali value: 1
key: a value: 1
key: living value: 1
key: alongside value: 1
key: caused value: 1
key: plate. value: 1
key: decreased value: 1
key: ago. value: 1
key: food value: 1
key: happened value: 1
key: factors value: 1
key: the value: 12
key: rift value: 1
key: with value: 1
key: evolve value: 1
key: what value: 1
key: radiation value: 1
key: african value: 2
key: selection. value: 1
key: there value: 1
key: to value: 4
key: combined value: 1
key: rifting value: 1
key: eurasia value: 1
key: reconnected value: 1
key: volcanic value: 1
key: first value: 1

Test word 'the' percentage: 0

Count of 'the': 12

Adding 'indubidubly': 
Count of 'indubidubly': 1
Adding 4 more...
Count of 'indubidubly': 5

感谢任何花时间阅读本文的人!

标签: javafilearraylisthashmappercentage

解决方案


因此,您发布了很多代码,但实际上您的问题在于这一行以及整数除法的使用。

int retval = map.get(token)/map.size(); //problem area

因此,在解决正在计算的内容之前,正如其他人所说,该行应如下所示。为了清楚起见,我引入了一些局部变量:

int freqOfToken = map.get(token);

// You'll have to write this method - iterate over HashMap and tally the
// total number words (or maintain it as you are building the Hashmap)
// (This is the `ag` variable/loop which you've added to post.)
int totalWords = getTotalWords();

// this computes a ratio of two integers yielding [0.0 1.0] (assuming the 
// numerator is always <= denominator which it should be in your problem) and
// converts it to a percent [0 100]
int retval = int (((double)freqOfToken / (double)totalWords) * 100);

因此,将比率计算为双精度(或浮点),将其缩放 100 并转换为 int。

有几种方法可以完成相同的操作(例如更改 'freqOfToken' 和 'totalWords'double以删除方程式中的演员表。

至于什么- 我将您的问题解释为“文件中所有标记(单词)的百分比是一个特定标记”。然而,您的实现没有多大意义,而是“文件中唯一单词的百分比是一个标记的出现次数”。

因此,您需要像上面那样更改等式,以使用单词总数作为除数(我看不到您有这个,所以我添加了一个您必须编写的新方法)。


推荐阅读