日期排列中最长的连续子序列
您好我有一个Arraylist
包含日期递增的顺序。日期格式为yyyy-MM-dd
。现在我想找出Arraylist
中最长的连续子序列。我在网上检查了解决方案,但它们与int数组有关,我想查找日期数组。 代码int数组:日期排列中最长的连续子序列
// Returns length of the longest contiguous subarray
int findLength(int arr[], int n)
{
int max_len = 1; // Initialize result
for (int i=0; i<n-1; i++)
{
// Initialize min and max for all subarrays starting with i
int mn = arr[i], mx = arr[i];
// Consider all subarrays starting with i and ending with j
for (int j=i+1; j<n; j++)
{
// Update min and max in this subarray if needed
mn = min(mn, arr[j]);
mx = max(mx, arr[j]);
// If current subarray has all contiguous elements
if ((mx - mn) == j-i)
max_len = max(max_len, mx-mn+1);
}
}
return max_len; // Return result
}
// Utility functions to find minimum and maximum of
// two elements
int min(int x, int y) { return (x < y)? x : y; }
int max(int x, int y) { return (x > y)? x : y; }
我解决了这个使用这个代码,如果任何人面临着同样的问题,他们可以使用以下代码:
private int getBest(){
//Getting dates
ArrayList<Date> successDates = new ArrayList<>();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
for(int i=0; i<successDays.size(); i++){
try {
successDates.add(sdf.parse(successDays.get(i)));
} catch (ParseException e) {
e.printStackTrace();
}
}
int max_len = 1;
for(int i=0; i<successDates.size(); i++){
Date mn = successDates.get(i);
Date mx = successDates.get(i);
for(int j=i+1; j<successDates.size(); j++){
if(mn.compareTo(successDates.get(j))>0){
mn = successDates.get(j);
}
if(mx.compareTo(successDates.get(j))<0){
mx = successDates.get(j);
}
if(getDaysBetweenDates(mn, mx) == j-i){
if(max_len < getDaysBetweenDates(mn, mx)+1){
max_len = getDaysBetweenDates(mn, mx) + 1;
}
}
}
}
return max_len;
}
private int getDaysBetweenDates(Date min, Date max){
Calendar mn = Calendar.getInstance();
mn.setTime(min);
Calendar mx = Calendar.getInstance();
mx.setTime(max);
long msDiff = mx.getTimeInMillis() - mn.getTimeInMillis();
return (int)TimeUnit.MILLISECONDS.toDays(msDiff);
}
FYI,旧的日期 - 时间类,例如['java.util.Date'](https://docs.oracle.com/javase/8/ docs/api/java/util/Date.html),['java.util.Calendar'](https://docs.oracle.com/javase/8/docs/api/java/util/Date.html),和'java.text.SimpleTextFormat'现在是[legacy](https://en.wikipedia.org/wiki/Legacy_system),由[java.time]代替(https://docs.oracle.com/javase/ 8/docs/api/java/time/package-summary.html)类。 –
TL;博士
ChronoUnit.DAYS.between (
LocalDate.parse(previousString) ,
LocalDate.parse(currentString)
)
字符串!= date
我有一个Arraylist co不断增加日期。日期的格式为yyyy-MM-dd。
这意味着你有一个String对象的List
,而不是日期。这里的主要挑战是获取日期对象,以便可以计算它们之间的日期。
java.time
现代的方式是与取代的麻烦旧的遗留类(Date
,Calendar
等)java.time类。
您的输入字符串碰巧符合标准ISO 8601格式。在解析/生成字符串时,java.time类默认情况下默认使用ISO 8601格式。所以不需要指定formatting pattern。
List<String> inputs = new ArrayList<>();
inputs.add ("2016-01-23");
inputs.add ("2016-01-25");
inputs.add ("2016-02-22"); // End of longest period between dates.
inputs.add ("2016-02-25");
inputs.add ("2016-02-28");
的LocalDate
类表示没有时间一天和不同时区的日期,唯一的价值。
此示例代码的策略是计算每个LocalDate
(从每个传入的字符串解析)和之前的LocalDate
之间的天数。如果超过目前为止所看到的最长时间,则忘记旧的最长时间并记住当前循环的数据。
LocalDate longestStart = null;
LocalDate longestStop = null;
LocalDate previousDate = null;
long longestInDays = 0;
的ChronoUnit
enum具有方便的方法,如计算经过的天。
for (String input : inputs) {
LocalDate currentDate = LocalDate.parse (input);
if (null == previousDate) { // First loop.
previousDate = currentDate;
continue; // Skip the rest of this first loop.
}
long currentDays = ChronoUnit.DAYS.between (previousDate , currentDate);
if (currentDays > longestInDays) {
// If the current loop exceeds previous longest, remember this one as longest.
longestInDays = currentDays;
longestStart = previousDate;
longestStop = currentDate;
}
// Prepare for next loop.
previousDate = currentDate;
}
将结果转储到控制台。
System.out.println ("Longest period has days: " + longestInDays + " = " + longestStart + "/" + longestStop);
最长周期具有天:28 = 2016年1月25日/ 2016年2月22日
谢谢@Basil Bourque –
它不直接修改的原因是这种方法检查“当前子数组是否具有所有连续元素”,而日期不是“连续元素”。您可以将日期视为“一年中的某些日子”或其他可能使其成为潜在连续元素的其他内容,但这不是直截了当的。 – alfasin
是的,我修改了这段代码,但它只工作了一个月 –