一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 利用Java快速查找21位花朵數示例代碼

利用Java快速查找21位花朵數示例代碼

2021-01-19 10:54蔣固金 Java教程

這篇文章主要給大家介紹了關于利用Java快速查找21位花朵數的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習,需要的朋友們下面隨著小編來一起學習學習吧。

前言

本文主要給大家介紹了關于利用Java快速查找21位花朵數的相關內容,分享出來供大家參考學習,下面話不多說了,來一起看看詳細的介紹吧。

以前備賽的時候遇到的算法題,求所有21位花朵數,分享一下,供大家參考,效率已經很高了。

示例代碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
package com.jianggujin;
 
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
 
/**
 * 水仙花數
 *
 * @author jianggujin
 *
 */
public class NarcissusNumber
{
 /**
 * 記錄10的0~N次方
 */
 private BigInteger[] powerOf10;
 /**
 * 記錄0到9中任意數字i的N次方乘以i出現的次數j的結果(i^N*j)
 */
 private BigInteger[][] preTable1;
 /**
 * 記錄離PreTable中對應數最近的10的k次方
 */
 private int[][] preTable2;
 /**
 * 記錄0到9中每個數出現的次數
 */
 private int[] selected = new int[10];
 /**
 * 記錄水仙花數的位數
 */
 private int length;
 
 /**
 * 記錄水仙花數
 */
 private List<BigInteger> results;
 /**
 * 記錄當前的進制
 */
 private int numberSystem = 10;
 
 /**
 * @param n
 *   水仙花數的位數
 */
 private NarcissusNumber(int n)
 {
  powerOf10 = new BigInteger[n + 1];
  powerOf10[0] = BigInteger.ONE;
  length = n;
  results = new ArrayList<BigInteger>();
 
  // 初始化powerPowerOf10
  for (int i = 1; i <= n; i++)
  {
   powerOf10[i] = powerOf10[i - 1].multiply(BigInteger.TEN);
  }
 
  preTable1 = new BigInteger[numberSystem][n + 1];
  preTable2 = new int[numberSystem][n + 1];
 
  // preTable[i][j] 0-i的N次方出現0-j次的值
  for (int i = 0; i < numberSystem; i++)
  {
   for (int j = 0; j <= n; j++)
   {
   preTable1[i][j] = new BigInteger(new Integer(i).toString()).pow(n)
     .multiply(new BigInteger(new Integer(j).toString()));
 
   for (int k = n; k >= 0; k--)
   {
    if (powerOf10[k].compareTo(preTable1[i][j]) < 0)
    {
     preTable2[i][j] = k;
     break;
    }
   }
   }
  }
 }
 
 public static List<BigInteger> search(int num)
 {
  NarcissusNumber narcissusNumber = new NarcissusNumber(num);
  narcissusNumber.search(narcissusNumber.numberSystem - 1, BigInteger.ZERO, narcissusNumber.length);
  return narcissusNumber.getResults();
 }
 
 /**
 * @param currentIndex
 *   記錄當前正在選擇的數字(0~9)
 * @param sum
 *   記錄當前值(如選了3個9、2個8 就是9^N*3+8^N*2)
 * @param remainCount
 *   記錄還可選擇多少數
 */
 private void search(int currentIndex, BigInteger sum, int remainCount)
 {
  if (sum.compareTo(powerOf10[length]) >= 0)
  {
   return;
  }
 
  if (remainCount == 0)
  {
   // 沒數可選時
   if (sum.compareTo(powerOf10[length - 1]) > 0 && check(sum))
   {
   results.add(sum);
   }
   return;
  }
 
  if (!preCheck(currentIndex, sum, remainCount))
  {
   return;
  }
 
  if (sum.add(preTable1[currentIndex][remainCount]).compareTo(powerOf10[length - 1]) < 0)// 見結束條件2
  {
   return;
  }
 
  if (currentIndex == 0)
  {
   // 選到0這個數時的處理
   selected[0] = remainCount;
   search(-1, sum, 0);
  }
  else
  {
   for (int i = 0; i <= remainCount; i++)
   {
   // 窮舉所選數可能出現的情況
   selected[currentIndex] = i;
   search(currentIndex - 1, sum.add(preTable1[currentIndex][i]), remainCount - i);
   }
  }
  // 到這里說明所選數currentIndex的所有情況都遍歷了
  selected[currentIndex] = 0;
 }
 
 /**
 * @param currentIndex
 *   記錄當前正在選擇的數字(0~9)
 * @param sum
 *   記錄當前值(如選了3個9、2個8 就是9^N*3+8^N*2)
 * @param remainCount
 *   記錄還可選擇多少數
 * @return 如果當前值符合條件返回true
 */
 private boolean preCheck(int currentIndex, BigInteger sum, int remainCount)
 {
  if (sum.compareTo(preTable1[currentIndex][remainCount]) < 0)// 判斷當前值是否小于PreTable中對應元素的值
  {
   return true;// 說明還有很多數沒選
  }
  BigInteger max = sum.add(preTable1[currentIndex][remainCount]);// 當前情況的最大值
  max = max.divide(powerOf10[preTable2[currentIndex][remainCount]]);// 取前面一部分比較
  sum = sum.divide(powerOf10[preTable2[currentIndex][remainCount]]);
 
  while (!max.equals(sum))
  {
   // 檢驗sum和max首部是否有相同的部分
   max = max.divide(BigInteger.TEN);
   sum = sum.divide(BigInteger.TEN);
  }
 
  if (max.equals(BigInteger.ZERO))// 無相同部分
  {
   return true;
  }
 
  int[] counter = getCounter(max);
 
  for (int i = 9; i > currentIndex; i--)
  {
   if (counter[i] > selected[i])// 見結束條件3
   {
   return false;
   }
  }
  for (int i = 0; i <= currentIndex; i++)
  {
   remainCount -= counter[i];
  }
  return remainCount >= 0;// 見結束條件4
 }
 
 /**
 * 檢查sum是否是花朵數
 *
 * @param sum
 *   記錄當前值(如選了3個9、2個8 就是9^N*3+8^N*2)
 * @return 如果sum存在于所選集合中返回true
 */
 private boolean check(BigInteger sum)
 {
  int[] counter = getCounter(sum);
  for (int i = 0; i < numberSystem; i++)
  {
   if (selected[i] != counter[i])
   {
   return false;
   }
  }
  return true;
 }
 
 /**
 * @param value
 *   需要檢驗的數
 * @return 返回value中0到9出現的次數的集合
 */
 private int[] getCounter(BigInteger value)
 {
  int[] counter = new int[numberSystem];
  char[] sumChar = value.toString().toCharArray();
 
  for (int i = 0; i < sumChar.length; i++)
  {
   counter[sumChar[i] - '0']++;
  }
 
  return counter;
 }
 
 /**
 * 獲得結果
 *
 * @return
 */
 public List<BigInteger> getResults()
 {
  return results;
 }
 
 public static void main(String[] args)
 {
  int num = 21;
  System.err.println("正在求解" + num + "位花朵數");
  long time = System.nanoTime();
  List<BigInteger> results = NarcissusNumber.search(num);
  time = System.nanoTime() - time;
  System.err.println("求解時間:\t" + time / 1000000000.0 + "s");
  System.err.println("求解結果:\t" + results);
 }
}

運行查看結果:

正在求解21位花朵數

求解時間: 0.327537257s

求解結果: [128468643043731391252, 449177399146038697307]

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。

原文鏈接:http://blog.csdn.net/jianggujin/article/details/53544720

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 男人天堂2023 | www.日本视频 | 亚洲阿v天堂在线2017 | 爱情岛论坛亚洲永久入口口 | 欧美一级精品 | vomoulei成人舞蹈 | 麻豆自拍 | 四虎国产一区 | 欧美又大又粗又爽视频 | 日韩精品视频观看 | 色先锋 影音先锋a 资源站 | 国产香蕉国产精品偷在线观看 | 亚洲国产精久久久久久久 | 91欧美国产 | 色无月| 日本强不卡在线观看 | 美女扒开屁股让男人进去 | 色姑娘久| b片在线观看| 久久免费黄色 | 亚洲精品国产国语 | 蜜色网| 91女神在线观看 | 久久视频在线视频观看天天看视频 | 精品日韩二区三区精品视频 | 久久精品国产只有精品 | 奇米影视小说 | 国产欧美久久久精品影院 | 国外欧美一区另类中文字幕 | 国产伦精品一区二区三区免费观看 | 果冻传媒九一制片厂网站 | 国产成人v爽在线免播放观看 | 全黄h全肉细节文在线观看 全彩成人18h漫画 | 美女扒开胸罩露出胸大乳 | ckinese中国男同gay男男 | 国产日韩欧美综合一区二区三区 | 无毛黄片| 韩日视频在线观看 | 成人性生交大片免费看软件 | 免费人成在线观看视频播放 | 高h全肉np触手 |