Вот решение с jQuery, которое работает как шарм. Он проверяет, больше ли высота окна больше высоты тела. Если это так, то он меняет верхний край нижнего колонтитула для компенсации. Тестирование в Firefox, Chrome, Safari и Opera.
$ (function () {var height_diff = $ (window) .height () - $ ('body') .height (); if (height_diff & gt; 0) {$ ('#footer') .css ('margin-top', height_diff);}});
Если ваш нижний колонтитул уже имеет верхний край (например, 50 пикселей), вам нужно будет изменить последнюю часть для:
css ( 'margin-top', height_diff + 50)
Ниже приведен отдельный пример того, как это сделать (не особо оптимизировано):
final Pattern p = Pattern.compile("^\\d+");
String[] examples = {
"1some", "2some", "20some", "21some", "3some", "some", "1abc", "abc"
};
Comparator<String> c = new Comparator<String>() {
@Override
public int compare(String object1, String object2) {
Matcher m = p.matcher(object1);
Integer number1 = null;
if (!m.find()) {
return object1.compareTo(object2);
}
else {
Integer number2 = null;
number1 = Integer.parseInt(m.group());
m = p.matcher(object2);
if (!m.find()) {
return object1.compareTo(object2);
}
else {
number2 = Integer.parseInt(m.group());
int comparison = number1.compareTo(number2);
if (comparison != 0) {
return comparison;
}
else {
return object1.compareTo(object2);
}
}
}
}
};
List<String> examplesList = new ArrayList<String>(Arrays.asList(examples));
Collections.sort(examplesList, c);
System.out.println(examplesList);
Выход
[1abc, 1some, 2some, 3some, 20some, 21some, abc, some]
Объяснение
Pattern
для определения того, находится ли число в исходной позиции String
. String
не присутствует, оно сравнивает его с второй. String
s как есть, снова Integer
s вместо целого String
s, следовательно, приводит к численному сравнению, а не лексикографическому String
s (спасибо MihaiC для определения этого) Это рабочее решение Java. Если у вас есть какие-либо предложения по коду, сообщите мне о моем Gist .
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class FB {
public static int comparator(String s1, String s2) {
String[] pt1 = s1.split("((?<=[a-z])(?=[0-9]))|((?<=[0-9])(?=[a-z]))");
String[] pt2 = s2.split("((?<=[a-z])(?=[0-9]))|((?<=[0-9])(?=[a-z]))");
//pt1 and pt2 arrays will have the string split in alphabets and numbers
int i=0;
if(Arrays.equals(pt1, pt2))
return 0;
else{
for(i=0;i<Math.min(pt1.length, pt2.length);i++)
if(!pt1[i].equals(pt2[i])) {
if(!isNumber(pt1[i],pt2[i])) {
if(pt1[i].compareTo(pt2[i])>0)
return 1;
else
return -1;
}
else {
int nu1 = Integer.parseInt(pt1[i]);
int nu2 = Integer.parseInt(pt2[i]);
if(nu1>nu2)
return 1;
else
return -1;
}
}
}
if(pt1.length>i)
return 1;
else
return -1;
}
private static Boolean isNumber(String n1, String n2) {
// TODO Auto-generated method stub
try {
int nu1 = Integer.parseInt(n1);
int nu2 = Integer.parseInt(n2);
return true;
}
catch(Exception x) {
return false;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
String[] examples = {"1some", "2some", "20some", "21some", "3some", "some", "1abc", "abc"};
List<String> values = new ArrayList<String>(Arrays.asList(examples));
System.out.println(values);
Comparator<String> com = (o1,o2) -> {return comparator(o1,o2);}; //lambda expression
Collections.sort(values,com);
System.out.println(values);
}
}
Вывод:
[1some, 2some, 20some, 21some, 3some, some, 1abc, abc]
[1abc, 1some, 2some, 3some, 20some, 21some, abc, some]
Вы можете сделать это ядро в одной строке, используя регулярное выражение для извлечения числовой части:
Collections.sort(selectedNodes, new Comparator<DefaultMutableTreeNode>() {
@Override
public int compare(DefaultMutableTreeNode o1,
DefaultMutableTreeNode o2) {
return Integer.parseInt(o1.getUserObject().toString().replaceAll("\\D", "")) -
Integer.parseInt(o2.getUserObject().toString().replaceAll("\\D", ""));
}
});
Сначала сделайте буквенно-цифровой компаратор, разделяющий строку в строковых или целых частях.
public class AlphaNumericalComparator implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
List<Object> parts1 = partsOf(o1);
List<Object> parts2 = partsOf(o2);
while (!parts1.isEmpty() && !parts2.isEmpty()) {
Object part1 = parts1.remove(0);
Object part2 = parts2.remove(0);
int cmp = 0;
if (part1 instanceof Integer && part2 instanceof Integer) {
cmp = Integer.compare((Integer)part1, (Integer)part2);
} else if (part1 instanceof String && part2 instanceof String) {
cmp = ((String) part1).compareTo((String) part2);
} else {
cmp = part1 instanceof String ? 1 : -1; // XXXa > XXX1
}
if (cmp != 0) {
return cmp;
}
}
if (parts1.isEmpty() && parts2.isEmpty()) {
return 0;
}
return parts1.isEmpty() ? -1 : 1;
}
private List<Object> partsOf(String s) {
List<Object> parts = new LinkedList<>();
int pos0 = 0;
int pos = 0;
boolean wasDigit = false;
while (true) {
if (pos >= s.length()
|| Character.isDigit(s.charAt(pos)) != wasDigit) {
if (pos > pos0) {
String part = s.substring(pos0, pos);
parts.add(wasDigit? Integer.valueOf(part) : part);
pos0 = pos;
}
if (pos >= s.length()) {
break;
}
wasDigit = !wasDigit;
}
++pos;
}
return parts;
}
};
Затем используйте этот компаратор в своем собственном, на Java 8 вы можете просто использовать статические методы компаратора.
Ваше решение лежит в Алфавитный алгоритм , и вы можете реализовать как этот
Вы не можете использовать стандартную String compareTo (), вместо этого нужно сравнить строки, следуя приведенному ниже алгоритму.
Повторите шаги.
String [] str = new String[]{"1some", "2some", "20some", "21some", "3some", "some"};
List<String> list = Arrays.asList(str);
Collections.sort(list, String.CASE_INSENSITIVE_ORDER);
System.out.println(list);
1some, 2some, 3some, 20some, 21some, some
.
– Radiodef
13 July 2018 в 14:49
Для выполнения этой пользовательской сортировки вам необходимо реализовать свой собственный Comparator
. По умолчанию метод String.compareTo()
сортирует числа перед символами. Когда 0
в 20some
сравнивается с s
в 3some
, 0
имеет более высокий приоритет сортировки, и поэтому все слово сортируется первым. Что вам нужно сделать, так это: попытайтесь разделить строки на число и часть символа. Это сложная задача, поскольку эти String
s могут состоять из многих из этих частей (или не так?). Вы можете использовать такие алгоритмы, как Alphanum
, которые Муртаза уже показал вам. Если вы хотите реализовать его самостоятельно, вы можете проверить, заканчивается ли числовая часть. Затем проанализируйте его с int
с помощью Integer.parse()
. Сравните int
части, если они существуют в обоих String
s, а затем сравните остальные. Ну, это может быть не самое профессиональное решение, но, как новичок, вы можете попробовать эти вещи сами изучить.
"abc
". перед"some"
. Хотя оба в конце, так как в лексикографическом сравнении приоритеты цифр над алфавитными символами. – Mena 27 November 2014 в 12:33